mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2026-03-17 19:23:34 +00:00
admin
This commit is contained in:
parent
d0850818d2
commit
40ce047612
7
admin/components.d.ts
vendored
7
admin/components.d.ts
vendored
@ -10,6 +10,7 @@ declare module '@vue/runtime-core' {
|
|||||||
Attachment: typeof import('./src/components/upload-attachment/attachment.vue')['default']
|
Attachment: typeof import('./src/components/upload-attachment/attachment.vue')['default']
|
||||||
DiyLink: typeof import('./src/components/diy-link/index.vue')['default']
|
DiyLink: typeof import('./src/components/diy-link/index.vue')['default']
|
||||||
Editor: typeof import('./src/components/editor/index.vue')['default']
|
Editor: typeof import('./src/components/editor/index.vue')['default']
|
||||||
|
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||||
ElAside: typeof import('element-plus/es')['ElAside']
|
ElAside: typeof import('element-plus/es')['ElAside']
|
||||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||||
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
|
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
|
||||||
@ -17,12 +18,14 @@ declare module '@vue/runtime-core' {
|
|||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
ElCard: typeof import('element-plus/es')['ElCard']
|
ElCard: typeof import('element-plus/es')['ElCard']
|
||||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||||
|
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||||
ElCol: typeof import('element-plus/es')['ElCol']
|
ElCol: typeof import('element-plus/es')['ElCol']
|
||||||
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||||
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||||
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
||||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||||
|
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||||
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
|
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
|
||||||
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
|
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
|
||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
@ -39,10 +42,12 @@ declare module '@vue/runtime-core' {
|
|||||||
ElImage: typeof import('element-plus/es')['ElImage']
|
ElImage: typeof import('element-plus/es')['ElImage']
|
||||||
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
|
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
ElMain: typeof import('element-plus/es')['ElMain']
|
ElMain: typeof import('element-plus/es')['ElMain']
|
||||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
|
ElOptionGroup: typeof import('element-plus/es')['ElOptionGroup']
|
||||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||||
@ -58,7 +63,9 @@ declare module '@vue/runtime-core' {
|
|||||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||||
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
|
ElTree: typeof import('element-plus/es')['ElTree']
|
||||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||||
Icon: typeof import('./src/components/icon/index.vue')['default']
|
Icon: typeof import('./src/components/icon/index.vue')['default']
|
||||||
PopoverInput: typeof import('./src/components/popover-input/index.vue')['default']
|
PopoverInput: typeof import('./src/components/popover-input/index.vue')['default']
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image" href="/niucloud.ico" />
|
<link rel="icon" type="image" href="/niucloud.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>管理端</title>
|
<title></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@ -13,7 +13,8 @@
|
|||||||
"@vueuse/core": "^9.12.0",
|
"@vueuse/core": "^9.12.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"axios": "^1.3.1",
|
"axios": "^1.4.0",
|
||||||
|
"crypto-js": "^4.1.1",
|
||||||
"css-color-function": "^1.3.3",
|
"css-color-function": "^1.3.3",
|
||||||
"echarts": "^5.4.1",
|
"echarts": "^5.4.1",
|
||||||
"element-plus": "^2.2.29",
|
"element-plus": "^2.2.29",
|
||||||
@ -25,6 +26,7 @@
|
|||||||
"vue": "^3.2.45",
|
"vue": "^3.2.45",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^4.1.6",
|
||||||
|
"vue-web-terminal": "^3.1.7",
|
||||||
"vue3-video-play": "^1.3.1-beta.6"
|
"vue3-video-play": "^1.3.1-beta.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
35
admin/src/api/addon.ts
Normal file
35
admin/src/api/addon.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地下载的插件列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getAddonLocal(params: Record<string, any>) {
|
||||||
|
return request.get('addon/local', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件详情
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getAddonDetial(id: number) {
|
||||||
|
return request.get(`addon/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安装插件
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function installAddon(params: Record<string, any>) {
|
||||||
|
return request.post(`addon/install/${params.addon}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卸载插件
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function uninstallAddon(params: Record<string, any>) {
|
||||||
|
return request.post(`addon/uninstall/${params.addon}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
@ -35,7 +35,7 @@ export function addArticle(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateArticle(params: Record<string, any>) {
|
export function editArticle(params: Record<string, any>) {
|
||||||
return request.put(`article/article/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`article/article/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ export function addArticleCategory(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateArticleCategory(params: Record<string, any>) {
|
export function editArticleCategory(params: Record<string, any>) {
|
||||||
return request.put(`article/category/${params.category_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`article/category/${params.category_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import request from '@/utils/request'
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function login(params: Record<string, any>) {
|
export function login(params: Record<string, any>, app_type: string) {
|
||||||
return request.get('login', { params, showErrorMessage: true })
|
return request.get(`login/${app_type}`, { params, showErrorMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,3 +24,11 @@ export function getAuthMenus() {
|
|||||||
export function getSiteInfo() {
|
export function getSiteInfo() {
|
||||||
return request.get('auth/site')
|
return request.get('auth/site')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取登录配置信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getLoginConfig() {
|
||||||
|
return request.get('login/config')
|
||||||
|
}
|
||||||
@ -8,7 +8,7 @@ import request from '@/utils/request'
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getDiyPageList(params: Record<string, any>) {
|
export function getDiyPageList(params: Record<string, any>) {
|
||||||
return request.get(`diy/diy`, {params})
|
return request.get(`diy/diy`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,15 +26,15 @@ export function getDiyPageInfo(id: number) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function addDiyPage(params: Record<string, any>) {
|
export function addDiyPage(params: Record<string, any>) {
|
||||||
return request.post('diy/diy', params, {showErrorMessage: true, showSuccessMessage: true})
|
return request.post('diy/diy', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑自定义页面
|
* 编辑自定义页面
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export function updateDiyPage(params: Record<string, any>) {
|
export function editDiyPage(params: Record<string, any>) {
|
||||||
return request.put(`diy/diy/${params.id}`, params, {showErrorMessage: true, showSuccessMessage: true})
|
return request.put(`diy/diy/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,15 +42,15 @@ export function updateDiyPage(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export function setUseDiyPage(params: Record<string, any>) {
|
export function setUseDiyPage(params: Record<string, any>) {
|
||||||
return request.put(`diy/use`, params, {showErrorMessage: true, showSuccessMessage: true})
|
return request.put(`diy/use`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改自定义页面分享内容
|
* 修改自定义页面分享内容
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export function updateDiyPageShare(params: Record<string, any>) {
|
export function editDiyPageShare(params: Record<string, any>) {
|
||||||
return request.put(`diy/diy/share`, params, {showErrorMessage: true, showSuccessMessage: true})
|
return request.put(`diy/diy/share`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,28 +59,28 @@ export function updateDiyPageShare(params: Record<string, any>) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function deleteDiyPage(id: number) {
|
export function deleteDiyPage(id: number) {
|
||||||
return request.delete(`diy/diy/${id}`, {showErrorMessage: true, showSuccessMessage: true})
|
return request.delete(`diy/diy/${id}`, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取自定义页面初始化数据
|
* 获取自定义页面初始化数据
|
||||||
*/
|
*/
|
||||||
export function initPage(params: Record<string, any>) {
|
export function initPage(params: Record<string, any>) {
|
||||||
return request.get(`diy/init`, {params})
|
return request.get(`diy/init`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取自定义链接列表
|
* 获取自定义链接列表
|
||||||
*/
|
*/
|
||||||
export function getLink(params: Record<string, any>) {
|
export function getLink(params: Record<string, any>) {
|
||||||
return request.get(`diy/link`, {params})
|
return request.get(`diy/link`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取底部导航数据
|
* 获取底部导航数据
|
||||||
*/
|
*/
|
||||||
export function getDiyBottom(params: Record<string, any>) {
|
export function getDiyBottom(params: Record<string, any>) {
|
||||||
return request.get(`diy/bottom`, {params})
|
return request.get(`diy/bottom`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,14 +89,14 @@ export function getDiyBottom(params: Record<string, any>) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function setDiyBottom(params: Record<string, any>) {
|
export function setDiyBottom(params: Record<string, any>) {
|
||||||
return request.post('diy/bottom', params, {showErrorMessage: true, showSuccessMessage: true})
|
return request.post('diy/bottom', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取页面类型
|
* 获取页面类型
|
||||||
*/
|
*/
|
||||||
export function getDiyPageType(params: Record<string, any>) {
|
export function getDiyPageType(params: Record<string, any>) {
|
||||||
return request.get(`diy/type`, {params})
|
return request.get(`diy/type`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,13 +105,21 @@ export function getDiyPageType(params: Record<string, any>) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getDiyRouteList(params: Record<string, any>) {
|
export function getDiyRouteList(params: Record<string, any>) {
|
||||||
return request.get(`diy/route`, {params})
|
return request.get(`diy/route`, { params })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义路由信息
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function getDiyRouteInfo(params: Record<string, any>) {
|
||||||
|
return request.get(`diy/route/info`, { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改路由页面分享内容
|
* 修改路由页面分享内容
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export function updateDiyRouteShare(params: Record<string, any>) {
|
export function editDiyRouteShare(params: Record<string, any>) {
|
||||||
return request.put(`diy/route/share`, params, {showErrorMessage: true, showSuccessMessage: true})
|
return request.put(`diy/route/share`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ import request from '@/utils/request'
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getMemberList(params: Record<string, any>) {
|
export function getMemberList(params: Record<string, any>) {
|
||||||
return request.get(`member/member`, {params})
|
return request.get(`member/member`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,6 +39,15 @@ export function getRegisterType(params: Record<string, any>) {
|
|||||||
return request.get(`member/registertype`, params)
|
return request.get(`member/registertype`, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员注册渠道
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getRegisterChannelType(params: Record<string, any>) {
|
||||||
|
return request.get(`member/register/channel`, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************** 会员标签 ****************************************************/
|
/***************************************************** 会员标签 ****************************************************/
|
||||||
@ -49,7 +58,7 @@ export function getRegisterType(params: Record<string, any>) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getMemberLabelList(params: Record<string, any>) {
|
export function getMemberLabelList(params: Record<string, any>) {
|
||||||
return request.get(`member/label`, {params})
|
return request.get(`member/label`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,20 +113,13 @@ export function getMemberLabelAll() {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateMemberDetail(params: Record<string, any>) {
|
export function editMemberDetail(params: Record<string, any>) {
|
||||||
return request.put(`member/member/modify/${params.member_id}/${params.field}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`member/member/modify/${params.member_id}/${params.field}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************** 会员零钱 ****************************************************/
|
/***************************************************** 会员零钱 ****************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取会员零钱列表
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getMoneyList(params: Record<string, any>) {
|
|
||||||
return request.get(`member/account/money`, {params})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************** 会员账户 ****************************************************/
|
/***************************************************** 会员账户 ****************************************************/
|
||||||
@ -146,7 +148,23 @@ export function getPointList(params: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function getBalanceList(params: Record<string, any>) {
|
export function getBalanceList(params: Record<string, any>) {
|
||||||
return request.get(`member/account/balance`, { params })
|
return request.get(`member/account/balance`, { params })
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取会员可提现余额列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getMoneyList(params: Record<string, any>) {
|
||||||
|
return request.get(`member/account/money`, { params })
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取会员佣金列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getCommissionList(params: Record<string, any>) {
|
||||||
|
return request.get(`member/account/commission`, { params })
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 会员积分调整
|
* 会员积分调整
|
||||||
* @param params
|
* @param params
|
||||||
@ -154,7 +172,7 @@ export function getBalanceList(params: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function adjustPoint(params: Record<string, any>) {
|
export function adjustPoint(params: Record<string, any>) {
|
||||||
return request.post(`member/account/point`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.post(`member/account/point`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 会员余额调整
|
* 会员余额调整
|
||||||
* @param params
|
* @param params
|
||||||
@ -162,7 +180,7 @@ export function adjustPoint(params: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function adjustBalance(params: Record<string, any>) {
|
export function adjustBalance(params: Record<string, any>) {
|
||||||
return request.post(`member/account/balance`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.post(`member/account/balance`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************** 会员相关设置 ****************************************************/
|
/***************************************************** 会员相关设置 ****************************************************/
|
||||||
|
|
||||||
@ -173,7 +191,7 @@ export function adjustBalance(params: Record<string, any>) {
|
|||||||
*/
|
*/
|
||||||
export function getLoginConfig(params: Record<string, any>) {
|
export function getLoginConfig(params: Record<string, any>) {
|
||||||
return request.get(`member/config/login`, params)
|
return request.get(`member/config/login`, params)
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 注册登录设置
|
* 注册登录设置
|
||||||
* @param params
|
* @param params
|
||||||
@ -183,21 +201,58 @@ export function setLoginConfig(params: Record<string, any>) {
|
|||||||
return request.post(`member/config/login`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.post(`member/config/login`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取会员转账方式
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getTransfertype() {
|
||||||
|
return request.get(`member/cash_out/transfertype`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 余额统计
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getBalanceSum(params: Record<string, any>) {
|
||||||
|
return request.get(`member/account/sum_balance`, { params })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 余额类型
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getBalanceStatus() {
|
||||||
|
return request.get(`member/account/type`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取余额变动类型
|
||||||
|
*/
|
||||||
|
export function getAccountType(params: Record<string, any>) {
|
||||||
|
return request.get(`member/account/change_type/${params.account_type}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************** 会员提现 ****************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取提现设置
|
* 获取提现设置
|
||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getWithdrawConfig() {
|
export function getWithdrawConfig() {
|
||||||
return request.get(`member/config/withdraw`)
|
return request.get(`member/config/cash_out`)
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 设置提现设置
|
* 设置提现设置
|
||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function setWithdrawConfig(params: Record<string, any>) {
|
export function setWithdrawConfig(params: Record<string, any>) {
|
||||||
return request.post(`member/config/withdraw`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.post(`member/config/cash_out`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,14 +261,53 @@ export function setWithdrawConfig(params: Record<string, any>) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getWithdrawList(params: Record<string, any>) {
|
export function getWithdrawList(params: Record<string, any>) {
|
||||||
return request.get(`member/withdraw`, {params})
|
return request.get(`member/cash_out`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取会员转账方式
|
* 会员提现详情
|
||||||
|
* @param params
|
||||||
|
* @returns id
|
||||||
|
*/
|
||||||
|
export function getWithdrawDetail(id: number) {
|
||||||
|
return request.get(`member/cash_out/${id}`, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员提现审核
|
||||||
|
* @param id
|
||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getTransfertype() {
|
export function memberAudit(params: Record<string, any>) {
|
||||||
return request.get(`member/withdraw/transfertype`)
|
return request.put(`member/cash_out/audit/${params.id}/${params.action}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员提现转账
|
||||||
|
* @param id
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function memberTransfer(params: Record<string, any>) {
|
||||||
|
return request.put(`member/cash_out/transfer/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员状态变更
|
||||||
|
* @param id
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function editMemberStatus(params: Record<string, any>) {
|
||||||
|
return request.put(`member/setstatus/${params.status}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员提现状态
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getWithdrawStatusList() {
|
||||||
|
return request.get(`member/cash_out/status`)
|
||||||
}
|
}
|
||||||
@ -1,75 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/***************************************************** 消息管理 ****************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息列表
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getMessageList() {
|
|
||||||
return request.get('message/message')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息详情
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getMessageInfo(key: string) {
|
|
||||||
return request.get(`message/message/${key}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发送记录
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getMessageLog(params: any) {
|
|
||||||
return request.get(`message/log`, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息启动与关闭
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function updateMessageStatus(params: Record<string, any>) {
|
|
||||||
return request.post(`message/message/updatestatus`, params, { showErrorMessage: true, showSuccessMessage: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息修改
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function updateMessage(params: Record<string, any>) {
|
|
||||||
return request.post(`message/message/update`, params, { showErrorMessage: true, showSuccessMessage: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 短信配置列表
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getSmsList() {
|
|
||||||
return request.get('message/message/sms')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 短信配置详情
|
|
||||||
* @param sms_type
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getSmsInfo(sms_type: string) {
|
|
||||||
return request.get(`message/message/sms/${sms_type}`,)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 短信配置修改
|
|
||||||
* @param sms_type
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function updateSms(params: Record<string, any>) {
|
|
||||||
return request.put(`message/message/sms/${params.sms_type}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
|
||||||
}
|
|
||||||
85
admin/src/api/notice.ts
Normal file
85
admin/src/api/notice.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/***************************************************** 消息管理 ****************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getNoticeList() {
|
||||||
|
return request.get('notice/notice')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息详情
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getNoticeInfo(key: string) {
|
||||||
|
return request.get(`notice/notice/${key}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送记录
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getNoticeLog(params: any) {
|
||||||
|
return request.get(`notice/log`, { params })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息启动与关闭
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function editNoticeStatus(params: Record<string, any>) {
|
||||||
|
return request.post(`notice/notice/editstatus`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息修改
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function editNotice(params: Record<string, any>) {
|
||||||
|
return request.post(`notice/notice/edit`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信配置列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getSmsList() {
|
||||||
|
return request.get('notice/notice/sms')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信配置详情
|
||||||
|
* @param sms_type
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getSmsInfo(sms_type: string) {
|
||||||
|
return request.get(`notice/notice/sms/${sms_type}`,)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信配置修改
|
||||||
|
* @param sms_type
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function editSms(params: Record<string, any>) {
|
||||||
|
return request.put(`notice/notice/sms/${params.sms_type}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送记录
|
||||||
|
* @param sms_type
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getSmsLog(params: Record<string, any>) {
|
||||||
|
return request.put(`notice/sms/log`, params)
|
||||||
|
}
|
||||||
@ -27,3 +27,27 @@ export function getRechargeOrderInfo(order_id: number) {
|
|||||||
export function getRechargeOrderStatusList() {
|
export function getRechargeOrderStatusList() {
|
||||||
return request.get(`order/recharge/status`)
|
return request.get(`order/recharge/status`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取退款记录
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getRefund(params: Record<string, any>) {
|
||||||
|
return request.get(`refund/refund`, { params })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取退款状态
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getRefundStatus() {
|
||||||
|
return request.get(`refund/status`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 充值订单发起退款
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function rechargeRefund(id) {
|
||||||
|
return request.get(`order/recharge/refund/${id}`);
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ import request from '@/utils/request'
|
|||||||
* 获取支付设置
|
* 获取支付设置
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getUserInfo(type:string) {
|
export function getUserInfo(type: string) {
|
||||||
return request.get(`auth/get`)
|
return request.get(`auth/get`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,6 +13,6 @@ export function getUserInfo(type:string) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function setUserInfo(params: Record<string, any>) {
|
export function setUserInfo(params: Record<string, any>) {
|
||||||
return request.put(`auth/update`, params, { showErrorMessage: true, showSuccessMessage: true });
|
return request.put(`auth/edit`, params, { showErrorMessage: true, showSuccessMessage: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import request from '@/utils/request'
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getSiteList(params: Record<string, any>) {
|
export function getSiteList(params: Record<string, any>) {
|
||||||
return request.get(`site/site`, {params})
|
return request.get(`site/site`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,7 +37,7 @@ export function addSite(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateSite(params: Record<string, any>) {
|
export function editSite(params: Record<string, any>) {
|
||||||
return request.put(`site/site/${params.site_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`site/site/${params.site_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ export function getStatusList() {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getSiteGroupList(params: Record<string, any>) {
|
export function getSiteGroupList(params: Record<string, any>) {
|
||||||
return request.get(`site/group`, {params})
|
return request.get(`site/group`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,7 +86,7 @@ export function addSiteGroup(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateSiteGroup(params: Record<string, any>) {
|
export function editSiteGroup(params: Record<string, any>) {
|
||||||
return request.put(`site/group/${params.group_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`site/group/${params.group_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ export function addUser(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateUser(params: Record<string, any>) {
|
export function editUser(params: Record<string, any>) {
|
||||||
return request.put(`site/user/${params.uid}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`site/user/${params.uid}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,14 @@ import request from '@/utils/request'
|
|||||||
export function getInfo() {
|
export function getInfo() {
|
||||||
return request.get('sys/role')
|
return request.get('sys/role')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getUrl() {
|
||||||
|
return request.get('sys/url')
|
||||||
|
}
|
||||||
/***************************************************** 用户组 ****************************************************/
|
/***************************************************** 用户组 ****************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +51,7 @@ export function addRole(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateRole(params: Record<string, any>) {
|
export function editRole(params: Record<string, any>) {
|
||||||
return request.put(`sys/role/${params.role_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`sys/role/${params.role_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +78,7 @@ export function allRole() {
|
|||||||
* 获取全部菜单
|
* 获取全部菜单
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getMenus(type:string) {
|
export function getMenus(type: string) {
|
||||||
return request.get(`sys/menu/${type}`)
|
return request.get(`sys/menu/${type}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +106,7 @@ export function addMenu(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateMenu(params: Record<string, any>) {
|
export function editMenu(params: Record<string, any>) {
|
||||||
return request.put(`sys/menu/${params.menu_key}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`sys/menu/${params.menu_key}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +188,7 @@ export function addAttachmentCategory(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateAttachmentCategory(params: Record<string, any>) {
|
export function editAttachmentCategory(params: Record<string, any>) {
|
||||||
return request.put(`sys/attachment/category/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`sys/attachment/category/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +216,7 @@ export function getAttachmentList(params: Record<string, any>) {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function deleteAttachment(params: Record<string, any>) {
|
export function deleteAttachment(params: Record<string, any>) {
|
||||||
return request.delete(`sys/attachment/del`, { data: params, showErrorMessage: true, showSuccessMessage: true})
|
return request.delete(`sys/attachment/del`, { data: params, showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -266,7 +274,7 @@ export function getStorageInfo(type: string) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateStorage(params: Record<string, any>) {
|
export function editStorage(params: Record<string, any>) {
|
||||||
return request.put(`sys/storage/${params.storage_type}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`sys/storage/${params.storage_type}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +284,7 @@ export function updateStorage(params: Record<string, any>) {
|
|||||||
* 获取支付设置
|
* 获取支付设置
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getPayConfig(type:string) {
|
export function getPayConfig(type: string) {
|
||||||
return request.get(`pay/config/${type}`)
|
return request.get(`pay/config/${type}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,13 +304,31 @@ export function getPayList() {
|
|||||||
return request.get(`pay/lists`)
|
return request.get(`pay/lists`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************** 打款设置 ****************************************************/
|
||||||
|
/**
|
||||||
|
* 获取打款设置配置
|
||||||
|
* @returns channel 渠道
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getTransferInfo(channel) {
|
||||||
|
return request.get(`pay/channel/lists/${channel}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置打款配置
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function setTransferInfo(params: Record<string, any>) {
|
||||||
|
return request.post(`pay/channel/set/transfer`, params)
|
||||||
|
}
|
||||||
/***************************************************** 定时任务 ****************************************************/
|
/***************************************************** 定时任务 ****************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务列表
|
* 获取任务列表
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getCronList(params:any) {
|
export function getCronList(params: any) {
|
||||||
return request.get(`sys/cron`, { params })
|
return request.get(`sys/cron`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +336,7 @@ export function getCronList(params:any) {
|
|||||||
* 任务详情
|
* 任务详情
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getCronInfo(id:string) {
|
export function getCronInfo(id: string) {
|
||||||
return request.get(`sys/cron/${id}`);
|
return request.get(`sys/cron/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +362,7 @@ export function getAgreementList() {
|
|||||||
* 协议详情
|
* 协议详情
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getAgreementInfo(key:string) {
|
export function getAgreementInfo(key: string) {
|
||||||
return request.get(`sys/agreement/${key}`);
|
return request.get(`sys/agreement/${key}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +370,7 @@ export function getAgreementInfo(key:string) {
|
|||||||
* 更新协议
|
* 更新协议
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateAgreement(params: Record<string, any>) {
|
export function editAgreement(params: Record<string, any>) {
|
||||||
return request.put(`sys/agreement/${params.key}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`sys/agreement/${params.key}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,3 +391,54 @@ export function getSceneDomain() {
|
|||||||
return request.get(`sys/scene_domain`);
|
return request.get(`sys/scene_domain`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************** 登录注册配置 ****************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理端登录注册配置
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getConfigLogin() {
|
||||||
|
return request.get(`sys/config/login`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置管理端登录注册配置
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function setConfigLogin(params: Record<string, any>) {
|
||||||
|
return request.put(`sys/config/login`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取支付设置
|
||||||
|
*/
|
||||||
|
export function getPayConfigList() {
|
||||||
|
return request.get(`pay/channel/lists`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置支付配置
|
||||||
|
*/
|
||||||
|
export function setPatConfig(params: Record<string, any>) {
|
||||||
|
return request.post(`pay/channel/set/all`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************** 刷新菜单 ****************************************************/
|
||||||
|
/**
|
||||||
|
* 刷新菜单
|
||||||
|
*/
|
||||||
|
export function menuRefresh(params: Record<string, any>) {
|
||||||
|
return request.post(`sys/menu/refresh`,{},{ showErrorMessage: true, showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************** 获取应用 ****************************************************/
|
||||||
|
/**
|
||||||
|
* 获取应用
|
||||||
|
*/
|
||||||
|
export function getAppMange() {
|
||||||
|
return request.get(`sys/applist`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import request from '@/utils/request'
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getGenerateTableList(params: Record<string, any>) {
|
export function getGenerateTableList(params: Record<string, any>) {
|
||||||
return request.get(`generator/generator`, {params})
|
return request.get(`generator/generator`, { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,7 +35,7 @@ export function addGenerateTable(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateGenerateTable(params: Record<string, any>) {
|
export function editGenerateTable(params: Record<string, any>) {
|
||||||
return request.put(`generator/generator/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`generator/generator/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,3 +66,11 @@ export function generateTable() {
|
|||||||
return request.get(`generator/table`)
|
return request.get(`generator/table`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取服务器环境配置
|
||||||
|
* @param file
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getSystem() {
|
||||||
|
return request.get(`sys/system`)
|
||||||
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export function addUser(params: Record<string, any>) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateUser(params: Record<string, any>) {
|
export function editUser(params: Record<string, any>) {
|
||||||
return request.put(`user/user/${params.uid}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put(`user/user/${params.uid}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export function getWechatStatic() {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateWechatConfig(params: Record<string, any>) {
|
export function editWechatConfig(params: Record<string, any>) {
|
||||||
return request.put('wechat/config', params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put('wechat/config', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ export function getWechatMenu() {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function updateWechatMenu(params: Record<string, any>) {
|
export function editWechatMenu(params: Record<string, any>) {
|
||||||
return request.put('wechat/menu', params, { showErrorMessage: true, showSuccessMessage: true })
|
return request.put('wechat/menu', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
admin/src/assets/images/back_login.jpg
Normal file
BIN
admin/src/assets/images/back_login.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
BIN
admin/src/assets/images/icon-addon.png
Normal file
BIN
admin/src/assets/images/icon-addon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 673 B |
BIN
admin/src/assets/images/login/login_index_bg.png
Normal file
BIN
admin/src/assets/images/login/login_index_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
BIN
admin/src/assets/images/login/login_index_left.png
Normal file
BIN
admin/src/assets/images/login/login_index_left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
BIN
admin/src/assets/images/site_login.png
Normal file
BIN
admin/src/assets/images/site_login.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@ -76,6 +76,7 @@
|
|||||||
import {cloneDeep} from 'lodash-es'
|
import {cloneDeep} from 'lodash-es'
|
||||||
import {getLink} from '@/api/diy';
|
import {getLink} from '@/api/diy';
|
||||||
import {ElMessage} from 'element-plus'
|
import {ElMessage} from 'element-plus'
|
||||||
|
import { CollectionTag } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@ -115,8 +116,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLink({}).then((res: any) => {
|
getLink({}).then((res: any) => {
|
||||||
if (res.code == 200) {
|
|
||||||
link.value = res.data;
|
link.value = res.data;
|
||||||
|
|
||||||
childList.value = link.value[0].child_list;
|
childList.value = link.value[0].child_list;
|
||||||
if (value.value.name != '') {
|
if (value.value.name != '') {
|
||||||
selectLink.value = cloneDeep(value.value);
|
selectLink.value = cloneDeep(value.value);
|
||||||
@ -126,7 +127,6 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
parentLinkName.value = selectLink.value.parent;
|
parentLinkName.value = selectLink.value.parent;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 选择父级链接
|
// 选择父级链接
|
||||||
|
|||||||
@ -37,8 +37,8 @@
|
|||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
|
|
||||||
let type = ref('element')
|
const type = ref('element')
|
||||||
let visible = ref('false')
|
const visible = ref('false')
|
||||||
|
|
||||||
// element 图标
|
// element 图标
|
||||||
const element = computed(() => {
|
const element = computed(() => {
|
||||||
@ -47,8 +47,8 @@ const element = computed(() => {
|
|||||||
|
|
||||||
// iconfont 图标
|
// iconfont 图标
|
||||||
const iconfont = computed(() => {
|
const iconfont = computed(() => {
|
||||||
let iconfile = import.meta.globEager('@/styles/iconfont.css')['/src/styles/iconfont.css'].default
|
const iconfile = import.meta.globEager('@/styles/icon/iconfont.css')['/src/styles/iconfont.css'].default
|
||||||
let icons = Array.from(iconfile.matchAll(/(icon.*)\:before/g))
|
const icons = Array.from(iconfile.matchAll(/(icon.*)\:before/g))
|
||||||
|
|
||||||
return icons.map(item => {
|
return icons.map(item => {
|
||||||
return item[1]
|
return item[1]
|
||||||
|
|||||||
@ -38,9 +38,15 @@
|
|||||||
<div class="attachment-list-wrap flex flex-col p-[15px] flex-1">
|
<div class="attachment-list-wrap flex flex-col p-[15px] flex-1">
|
||||||
<el-row :gutter="15" class="h-[32px]">
|
<el-row :gutter="15" class="h-[32px]">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
<div class="flex">
|
||||||
<el-upload v-bind="upload" ref="uploadRef">
|
<el-upload v-bind="upload" ref="uploadRef">
|
||||||
<el-button type="primary">{{ t('upload.upload' + type) }}</el-button>
|
<el-button type="primary">{{ t('upload.upload' + type) }}</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
<el-button v-if="operate === false" class="ml-[10px]" type="primary" @click="operate = true">{{
|
||||||
|
t('edit') }}</el-button>
|
||||||
|
<el-button v-else class="ml-[10px]" type="primary" @click="operate = false">{{ t('complete')
|
||||||
|
}}</el-button>
|
||||||
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" class="text-right">
|
<el-col :span="12" class="text-right">
|
||||||
<el-input v-model="attachmentParam.real_name" class="m-0 w-[200px]"
|
<el-input v-model="attachmentParam.real_name" class="m-0 w-[200px]"
|
||||||
@ -50,7 +56,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<div class="flex-1 my-[15px] h-0" v-loading="attachment.loading">
|
<div class="flex-1 my-[15px] h-0" v-loading="attachment.loading">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<div class="flex flex-wrap" v-if="attachment.data.length">
|
<div class="flex flex-wrap" v-if="attachment.data.length && operate === true">
|
||||||
<div class="attachment-item mr-[10px]" :class="scene == 'select' ? 'w-[100px]' : 'w-[120px]'"
|
<div class="attachment-item mr-[10px]" :class="scene == 'select' ? 'w-[100px]' : 'w-[120px]'"
|
||||||
v-for="(item, index) in attachment.data" :key="index">
|
v-for="(item, index) in attachment.data" :key="index">
|
||||||
<div class="attachment-wrap w-full rounded cursor-pointer overflow-hidden relative flex items-center justify-center"
|
<div class="attachment-wrap w-full rounded cursor-pointer overflow-hidden relative flex items-center justify-center"
|
||||||
@ -94,13 +100,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-wrap" v-else-if="attachment.data.length && operate === false">
|
||||||
|
<div class="attachment-item mr-[10px] w-[120px]" v-for="(item, index) in attachment.data"
|
||||||
|
:key="index">
|
||||||
|
<div
|
||||||
|
class="attachment-wrap w-full rounded cursor-pointer overflow-hidden relative flex items-center justify-center h-[120px]">
|
||||||
|
<el-image :src="img(item.url)" fit="contain" v-if="type == 'image'"
|
||||||
|
:preview-src-list="item.image_list"></el-image>
|
||||||
|
<video :src="img(item.url)" v-else></video>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<el-tooltip placement="top">
|
||||||
|
<template #content>{{ item.real_name }}</template>
|
||||||
|
<div class="truncate my-[10px] cursor-pointer text-base flex-1 ">
|
||||||
|
{{ item.real_name }}
|
||||||
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex items-center justify-center" v-else>
|
<div class="flex items-center justify-center" v-else>
|
||||||
<el-empty :description="t('upload.attachmentEmpty')" :image-size="100" />
|
<el-empty v-if="!attachment.loading" :description="t('upload.attachmentEmpty')" :image-size="100" />
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="8" v-if="scene == 'attachment'">
|
<el-col :span="8" v-if="scene == 'attachment' && operate === true">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<el-checkbox v-model="selectAll" :label="t('selectAll')" size="large" />
|
<el-checkbox v-model="selectAll" :label="t('selectAll')" size="large" />
|
||||||
<el-button class="ml-[15px]" :disabled="batchOperateDisabled" @click="deleteAttachmentEvent()">{{
|
<el-button class="ml-[15px]" :disabled="batchOperateDisabled" @click="deleteAttachmentEvent()">{{
|
||||||
@ -163,7 +188,7 @@ import {
|
|||||||
getAttachmentCategoryList as attachmentCategoryList,
|
getAttachmentCategoryList as attachmentCategoryList,
|
||||||
getAttachmentList as attachmentList,
|
getAttachmentList as attachmentList,
|
||||||
addAttachmentCategory as addCategory,
|
addAttachmentCategory as addCategory,
|
||||||
updateAttachmentCategory as updateCategory,
|
editAttachmentCategory as updateCategory,
|
||||||
deleteAttachmentCategory as deleteCategory,
|
deleteAttachmentCategory as deleteCategory,
|
||||||
deleteAttachment,
|
deleteAttachment,
|
||||||
moveAttachment
|
moveAttachment
|
||||||
@ -172,6 +197,7 @@ import { debounce, img, getToken } from '@/utils/common'
|
|||||||
import { ElMessage, UploadFile, UploadFiles, ElMessageBox } from 'element-plus'
|
import { ElMessage, UploadFile, UploadFiles, ElMessageBox } from 'element-plus'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
|
|
||||||
|
const operate = ref(false)
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
// 选择数量限制
|
// 选择数量限制
|
||||||
limit: {
|
limit: {
|
||||||
@ -196,7 +222,7 @@ const attachmentCategory: Record<string, any> = reactive({
|
|||||||
data: []
|
data: []
|
||||||
})
|
})
|
||||||
const attachment: Record<string, any> = reactive({
|
const attachment: Record<string, any> = reactive({
|
||||||
loading: false,
|
loading: true,
|
||||||
page: 1,
|
page: 1,
|
||||||
total: 0,
|
total: 0,
|
||||||
limit: prop.scene == 'select' ? 10 : 20,
|
limit: prop.scene == 'select' ? 10 : 20,
|
||||||
@ -241,6 +267,13 @@ const getAttachmentList = debounce((page: number = 1) => {
|
|||||||
attachment.total = res.data.total
|
attachment.total = res.data.total
|
||||||
attachment.loading = false
|
attachment.loading = false
|
||||||
prop.scene == 'attachment' && clearSelected()
|
prop.scene == 'attachment' && clearSelected()
|
||||||
|
|
||||||
|
for (let i = 0; i < attachment.data.length; i++) {
|
||||||
|
attachment.data[i]['image_list'] = []
|
||||||
|
attachment.data[i]['image_list'].push(img(res.data.data[i]['url']))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
attachment.loading = false
|
attachment.loading = false
|
||||||
})
|
})
|
||||||
@ -508,5 +541,4 @@ defineExpose({
|
|||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
box-shadow: var(--el-box-shadow-light);
|
box-shadow: var(--el-box-shadow-light);
|
||||||
}
|
}
|
||||||
}
|
}</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ const prop = defineProps({
|
|||||||
},
|
},
|
||||||
api: {
|
api: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'sys/document'
|
default: 'sys/document/document'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ const upload: Record<string, any> = {
|
|||||||
action: `${import.meta.env.VITE_APP_BASE_URL}/${prop.api}`,
|
action: `${import.meta.env.VITE_APP_BASE_URL}/${prop.api}`,
|
||||||
showFileList: false,
|
showFileList: false,
|
||||||
headers: {},
|
headers: {},
|
||||||
accept: '.doc,.docx,.xml,.txt,.pem,.zip,.rar,.7z',
|
accept: '.doc,.docx,.xml,.txt,.pem,.zip,.rar,.7z,.crt',
|
||||||
onSuccess: (response: any, uploadFile: UploadFile) => {
|
onSuccess: (response: any, uploadFile: UploadFile) => {
|
||||||
value.value = response.data.url
|
value.value = response.data.url
|
||||||
ElMessage({
|
ElMessage({
|
||||||
|
|||||||
434
admin/src/components/verifition/Verify.vue
Normal file
434
admin/src/components/verifition/Verify.vue
Normal file
File diff suppressed because one or more lines are too long
260
admin/src/components/verifition/Verify/VerifyPoints.vue
Normal file
260
admin/src/components/verifition/Verify/VerifyPoints.vue
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<div style="position: relative"
|
||||||
|
>
|
||||||
|
<div class="verify-img-out">
|
||||||
|
<div class="verify-img-panel" :style="{'width': setSize.imgWidth,
|
||||||
|
'height': setSize.imgHeight,
|
||||||
|
'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
|
||||||
|
'margin-bottom': vSpace + 'px'}"
|
||||||
|
>
|
||||||
|
<div class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
|
||||||
|
<i class="iconfont icon-refresh"></i>
|
||||||
|
</div>
|
||||||
|
<img :src="'data:image/png;base64,'+pointBackImgBase"
|
||||||
|
ref="canvas"
|
||||||
|
alt="" style="width:100%;height:100%;display:block"
|
||||||
|
@click="bindingClick?canvasClick($event):undefined">
|
||||||
|
|
||||||
|
<div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area"
|
||||||
|
:style="{
|
||||||
|
'background-color':'#1abd6c',
|
||||||
|
color:'#fff',
|
||||||
|
'z-index':9999,
|
||||||
|
width:'20px',
|
||||||
|
height:'20px',
|
||||||
|
'text-align':'center',
|
||||||
|
'line-height':'20px',
|
||||||
|
'border-radius': '50%',
|
||||||
|
position:'absolute',
|
||||||
|
top:parseInt(tempPoint.y-10) + 'px',
|
||||||
|
left:parseInt(tempPoint.x-10) + 'px'
|
||||||
|
}">
|
||||||
|
{{index + 1}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 'height': this.barSize.height, -->
|
||||||
|
<div class="verify-bar-area"
|
||||||
|
:style="{'width': setSize.imgWidth,
|
||||||
|
'color': this.barAreaColor,
|
||||||
|
'border-color': this.barAreaBorderColor,
|
||||||
|
'line-height':this.barSize.height}">
|
||||||
|
<span class="verify-msg">{{text}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script type="text/babel">
|
||||||
|
/**
|
||||||
|
* VerifyPoints
|
||||||
|
* @description 点选
|
||||||
|
* */
|
||||||
|
import {resetSize, _code_chars, _code_color1, _code_color2} from './../utils/util'
|
||||||
|
import {aesEncrypt} from "./../utils/ase"
|
||||||
|
import {reqGet,reqCheck} from "./../api/index"
|
||||||
|
import { computed, onMounted, reactive, ref,watch,nextTick,toRefs, watchEffect,getCurrentInstance} from 'vue';
|
||||||
|
export default {
|
||||||
|
name: 'VerifyPoints',
|
||||||
|
props: {
|
||||||
|
//弹出式pop,固定fixed
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'fixed'
|
||||||
|
},
|
||||||
|
captchaType:{
|
||||||
|
type:String,
|
||||||
|
},
|
||||||
|
//间隔
|
||||||
|
vSpace: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
imgSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '155px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
barSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '40px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props,context){
|
||||||
|
const {mode,captchaType,vSpace,imgSize,barSize} = toRefs(props)
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
let secretKey = ref(''), //后端返回的ase加密秘钥
|
||||||
|
checkNum = ref(3), //默认需要点击的字数
|
||||||
|
fontPos = reactive([]), //选中的坐标信息
|
||||||
|
checkPosArr = reactive([]), //用户点击的坐标
|
||||||
|
num = ref(1), //点击的记数
|
||||||
|
pointBackImgBase = ref(''), //后端获取到的背景图片
|
||||||
|
poinTextList = reactive([]), //后端返回的点击字体顺序
|
||||||
|
backToken = ref(''), //后端返回的token值
|
||||||
|
setSize = reactive({
|
||||||
|
imgHeight: 0,
|
||||||
|
imgWidth: 0,
|
||||||
|
barHeight: 0,
|
||||||
|
barWidth: 0
|
||||||
|
}),
|
||||||
|
tempPoints = reactive([]),
|
||||||
|
text = ref(''),
|
||||||
|
barAreaColor = ref(undefined),
|
||||||
|
barAreaBorderColor = ref(undefined),
|
||||||
|
showRefresh = ref(true),
|
||||||
|
bindingClick = ref(true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const init = ()=>{
|
||||||
|
//加载页面
|
||||||
|
fontPos.splice(0, fontPos.length)
|
||||||
|
checkPosArr.splice(0, checkPosArr.length)
|
||||||
|
num.value = 1
|
||||||
|
getPictrue();
|
||||||
|
nextTick(() => {
|
||||||
|
let {imgHeight,imgWidth,barHeight,barWidth} = resetSize(proxy)
|
||||||
|
setSize.imgHeight = imgHeight
|
||||||
|
setSize.imgWidth = imgWidth
|
||||||
|
setSize.barHeight = barHeight
|
||||||
|
setSize.barWidth = barWidth
|
||||||
|
proxy.$parent.$emit('ready', proxy)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMounted(()=>{
|
||||||
|
// 禁止拖拽
|
||||||
|
init()
|
||||||
|
proxy.$el.onselectstart = function () {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const canvas = ref(null)
|
||||||
|
const canvasClick = (e)=>{
|
||||||
|
checkPosArr.push(getMousePos(canvas, e));
|
||||||
|
if (num.value == checkNum.value) {
|
||||||
|
num.value = createPoint(getMousePos(canvas, e));
|
||||||
|
//按比例转换坐标值
|
||||||
|
let arr = pointTransfrom(checkPosArr,setSize)
|
||||||
|
checkPosArr.length = 0
|
||||||
|
checkPosArr.push(...arr);
|
||||||
|
//等创建坐标执行完
|
||||||
|
setTimeout(() => {
|
||||||
|
// var flag = this.comparePos(this.fontPos, this.checkPosArr);
|
||||||
|
//发送后端请求
|
||||||
|
var captchaVerification = secretKey.value? aesEncrypt(backToken.value+'---'+JSON.stringify(checkPosArr),secretKey.value):backToken.value+'---'+JSON.stringify(checkPosArr)
|
||||||
|
let data = {
|
||||||
|
captchaType:captchaType.value,
|
||||||
|
"captcha_code":secretKey.value? aesEncrypt(JSON.stringify(checkPosArr),secretKey.value):JSON.stringify(checkPosArr),
|
||||||
|
"captcha_key":backToken.value
|
||||||
|
}
|
||||||
|
reqCheck(data).then(res=>{
|
||||||
|
if (res.code == "200") {
|
||||||
|
barAreaColor.value = '#4cae4c'
|
||||||
|
barAreaBorderColor.value = '#5cb85c'
|
||||||
|
text.value = '验证成功'
|
||||||
|
bindingClick.value = false
|
||||||
|
if (mode.value=='pop') {
|
||||||
|
setTimeout(()=>{
|
||||||
|
proxy.$parent.clickShow = false;
|
||||||
|
refresh();
|
||||||
|
},1500)
|
||||||
|
}
|
||||||
|
proxy.$parent.$emit('success', {captchaVerification})
|
||||||
|
}else{
|
||||||
|
proxy.$parent.$emit('error', proxy)
|
||||||
|
barAreaColor.value = '#d9534f'
|
||||||
|
barAreaBorderColor.value = '#d9534f'
|
||||||
|
text.value = '验证失败'
|
||||||
|
setTimeout(() => {
|
||||||
|
refresh();
|
||||||
|
}, 700);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
if (num.value < checkNum.value) {
|
||||||
|
num.value = createPoint(getMousePos(canvas, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取坐标
|
||||||
|
const getMousePos = function (obj, e) {
|
||||||
|
var x = e.offsetX
|
||||||
|
var y = e.offsetY
|
||||||
|
return {x, y}
|
||||||
|
}
|
||||||
|
//创建坐标点
|
||||||
|
const createPoint = function (pos) {
|
||||||
|
tempPoints.push(Object.assign({}, pos))
|
||||||
|
return num.value+1;
|
||||||
|
}
|
||||||
|
const refresh = function () {
|
||||||
|
tempPoints.splice(0, tempPoints.length)
|
||||||
|
barAreaColor.value = '#000'
|
||||||
|
barAreaBorderColor.value = '#ddd'
|
||||||
|
bindingClick.value = true
|
||||||
|
fontPos.splice(0, fontPos.length)
|
||||||
|
checkPosArr.splice(0, checkPosArr.length)
|
||||||
|
num.value = 1
|
||||||
|
getPictrue();
|
||||||
|
text.value = '验证失败'
|
||||||
|
showRefresh.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求背景图片和验证图片
|
||||||
|
function getPictrue() {
|
||||||
|
let data = {
|
||||||
|
captchaType:captchaType.value
|
||||||
|
}
|
||||||
|
reqGet(data).then(res=>{
|
||||||
|
if (res.code == "200") {
|
||||||
|
pointBackImgBase.value = res.data.originalImageBase64
|
||||||
|
backToken.value = res.data.token
|
||||||
|
secretKey.value = res.data.secretKey
|
||||||
|
poinTextList.value = res.data.wordList
|
||||||
|
text.value = '请依次点击【' + poinTextList.value.join(",") + '】'
|
||||||
|
}else{
|
||||||
|
text.value = res.msg;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//坐标转换函数
|
||||||
|
const pointTransfrom = function(pointArr,imgSize){
|
||||||
|
var newPointArr = pointArr.map(p=>{
|
||||||
|
let x = Math.round(310 * p.x/parseInt(imgSize.imgWidth))
|
||||||
|
let y =Math.round(155 * p.y/parseInt(imgSize.imgHeight))
|
||||||
|
return {x,y}
|
||||||
|
})
|
||||||
|
return newPointArr
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
secretKey,
|
||||||
|
checkNum,
|
||||||
|
fontPos,
|
||||||
|
checkPosArr,
|
||||||
|
num,
|
||||||
|
pointBackImgBase,
|
||||||
|
poinTextList,
|
||||||
|
backToken,
|
||||||
|
setSize,
|
||||||
|
tempPoints,
|
||||||
|
text,
|
||||||
|
barAreaColor,
|
||||||
|
barAreaBorderColor,
|
||||||
|
showRefresh,
|
||||||
|
bindingClick,
|
||||||
|
init,
|
||||||
|
canvas,
|
||||||
|
canvasClick,
|
||||||
|
getMousePos,createPoint,refresh,getPictrue,pointTransfrom
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
366
admin/src/components/verifition/Verify/VerifySlide.vue
Normal file
366
admin/src/components/verifition/Verify/VerifySlide.vue
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
<template>
|
||||||
|
<div style="position: relative;">
|
||||||
|
<div v-if="type === '2'" class="verify-img-out"
|
||||||
|
:style="{height: (parseInt(setSize.imgHeight) + vSpace) + 'px'}"
|
||||||
|
>
|
||||||
|
<div class="verify-img-panel" :style="{width: setSize.imgWidth,
|
||||||
|
height: setSize.imgHeight,}">
|
||||||
|
<img :src="'data:image/png;base64,'+backImgBase" alt="" style="width:100%;height:100%;display:block">
|
||||||
|
<div class="verify-refresh" @click="refresh" v-show="showRefresh"><i class="iconfont icon-refresh"></i>
|
||||||
|
</div>
|
||||||
|
<transition name="tips">
|
||||||
|
<span class="verify-tips" v-if="tipWords" :class="passFlag ?'suc-bg':'err-bg'">{{tipWords}}</span>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 公共部分 -->
|
||||||
|
<div class="verify-bar-area" :style="{width: setSize.imgWidth,
|
||||||
|
height: barSize.height,
|
||||||
|
'line-height':barSize.height}">
|
||||||
|
<span class="verify-msg" v-text="text"></span>
|
||||||
|
<div class="verify-left-bar"
|
||||||
|
:style="{width: (leftBarWidth!==undefined)?leftBarWidth: barSize.height, height: barSize.height, 'border-color': leftBarBorderColor, transaction: transitionWidth}">
|
||||||
|
<span class="verify-msg" v-text="finishText"></span>
|
||||||
|
<div class="verify-move-block"
|
||||||
|
@touchstart="start"
|
||||||
|
@mousedown="start"
|
||||||
|
:style="{width: barSize.height, height: barSize.height, 'background-color': moveBlockBackgroundColor, left: moveBlockLeft, transition: transitionLeft}">
|
||||||
|
<i :class="['verify-icon iconfont', iconClass]"
|
||||||
|
:style="{color: iconColor}"></i>
|
||||||
|
<div v-if="type === '2'" class="verify-sub-block"
|
||||||
|
:style="{'width':Math.floor(parseInt(setSize.imgWidth)*47/310)+ 'px',
|
||||||
|
'height': setSize.imgHeight,
|
||||||
|
'top':'-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
|
||||||
|
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
|
||||||
|
}">
|
||||||
|
<img :src="'data:image/png;base64,'+blockBackImgBase" alt="" style="width:100%;height:100%;display:block;-webkit-user-drag:none;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script type="text/babel">
|
||||||
|
/**
|
||||||
|
* VerifySlide
|
||||||
|
* @description 滑块
|
||||||
|
* */
|
||||||
|
import {aesEncrypt} from "./../utils/ase"
|
||||||
|
import {resetSize} from './../utils/util'
|
||||||
|
import {reqGet,reqCheck} from "./../api/index"
|
||||||
|
import { computed, onMounted, reactive, ref,watch,nextTick,toRefs, watchEffect,getCurrentInstance} from 'vue';
|
||||||
|
// "captchaType":"blockPuzzle",
|
||||||
|
export default {
|
||||||
|
name: 'VerifySlide',
|
||||||
|
props: {
|
||||||
|
captchaType:{
|
||||||
|
type:String,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: '1'
|
||||||
|
},
|
||||||
|
//弹出式pop,固定fixed
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'fixed'
|
||||||
|
},
|
||||||
|
vSpace: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
explain: {
|
||||||
|
type: String,
|
||||||
|
default: '向右滑动完成验证'
|
||||||
|
},
|
||||||
|
imgSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '155px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blockSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '50px',
|
||||||
|
height: '50px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
barSize: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
width: '310px',
|
||||||
|
height: '40px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props,context){
|
||||||
|
const {mode,captchaType,vSpace,imgSize,barSize,type,blockSize,explain} = toRefs(props)
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
let secretKey = ref(''), //后端返回的ase加密秘钥
|
||||||
|
passFlag = ref(''), //是否通过的标识
|
||||||
|
backImgBase = ref(''), //验证码背景图片
|
||||||
|
blockBackImgBase = ref(''), //验证滑块的背景图片
|
||||||
|
backToken = ref(''), //后端返回的唯一token值
|
||||||
|
startMoveTime = ref(''), //移动开始的时间
|
||||||
|
endMovetime = ref(''), //移动结束的时间
|
||||||
|
tipsBackColor = ref(''), //提示词的背景颜色
|
||||||
|
tipWords = ref(''),
|
||||||
|
text = ref(''),
|
||||||
|
finishText = ref(''),
|
||||||
|
setSize = reactive({
|
||||||
|
imgHeight: 0,
|
||||||
|
imgWidth: 0,
|
||||||
|
barHeight: 0,
|
||||||
|
barWidth: 0
|
||||||
|
}),
|
||||||
|
top = ref(0),
|
||||||
|
left = ref(0),
|
||||||
|
moveBlockLeft = ref(undefined),
|
||||||
|
leftBarWidth = ref(undefined),
|
||||||
|
// 移动中样式
|
||||||
|
moveBlockBackgroundColor = ref(undefined),
|
||||||
|
leftBarBorderColor = ref('#ddd'),
|
||||||
|
iconColor = ref(undefined),
|
||||||
|
iconClass = ref('icon-right'),
|
||||||
|
status = ref(false), //鼠标状态
|
||||||
|
isEnd = ref(false) , //是够验证完成
|
||||||
|
showRefresh = ref(true),
|
||||||
|
transitionLeft = ref(''),
|
||||||
|
transitionWidth = ref(''),
|
||||||
|
startLeft = ref(0)
|
||||||
|
|
||||||
|
const barArea = computed(()=>{
|
||||||
|
return proxy.$el.querySelector('.verify-bar-area')
|
||||||
|
})
|
||||||
|
function init() {
|
||||||
|
text.value = explain.value
|
||||||
|
getPictrue();
|
||||||
|
nextTick(() => {
|
||||||
|
let {imgHeight,imgWidth,barHeight,barWidth} = resetSize(proxy)
|
||||||
|
setSize.imgHeight = imgHeight
|
||||||
|
setSize.imgWidth = imgWidth
|
||||||
|
setSize.barHeight = barHeight
|
||||||
|
setSize.barWidth = barWidth
|
||||||
|
proxy.$parent.$emit('ready', proxy)
|
||||||
|
})
|
||||||
|
|
||||||
|
window.removeEventListener("touchmove", function (e) {
|
||||||
|
move(e);
|
||||||
|
});
|
||||||
|
window.removeEventListener("mousemove", function (e) {
|
||||||
|
move(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
//鼠标松开
|
||||||
|
window.removeEventListener("touchend", function () {
|
||||||
|
end();
|
||||||
|
});
|
||||||
|
window.removeEventListener("mouseup", function () {
|
||||||
|
end();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("touchmove", function (e) {
|
||||||
|
move(e);
|
||||||
|
});
|
||||||
|
window.addEventListener("mousemove", function (e) {
|
||||||
|
move(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
//鼠标松开
|
||||||
|
window.addEventListener("touchend", function () {
|
||||||
|
end();
|
||||||
|
});
|
||||||
|
window.addEventListener("mouseup", function () {
|
||||||
|
end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
watch(type,()=>{
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
onMounted(()=>{
|
||||||
|
// 禁止拖拽
|
||||||
|
init()
|
||||||
|
proxy.$el.onselectstart = function () {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//鼠标按下
|
||||||
|
function start(e) {
|
||||||
|
e = e || window.event
|
||||||
|
if (!e.touches) { //兼容PC端
|
||||||
|
var x = e.clientX;
|
||||||
|
} else { //兼容移动端
|
||||||
|
var x = e.touches[0].pageX;
|
||||||
|
}
|
||||||
|
console.log(barArea);
|
||||||
|
startLeft.value =Math.floor(x - barArea.value.getBoundingClientRect().left);
|
||||||
|
startMoveTime.value = +new Date(); //开始滑动的时间
|
||||||
|
if (isEnd.value == false) {
|
||||||
|
text.value = ''
|
||||||
|
moveBlockBackgroundColor.value = '#337ab7'
|
||||||
|
leftBarBorderColor.value = '#337AB7'
|
||||||
|
iconColor.value = '#fff'
|
||||||
|
e.stopPropagation();
|
||||||
|
status.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//鼠标移动
|
||||||
|
function move(e) {
|
||||||
|
e = e || window.event
|
||||||
|
if (status.value && isEnd.value == false) {
|
||||||
|
if (!e.touches) { //兼容PC端
|
||||||
|
var x = e.clientX;
|
||||||
|
} else { //兼容移动端
|
||||||
|
var x = e.touches[0].pageX;
|
||||||
|
}
|
||||||
|
var bar_area_left = barArea.value.getBoundingClientRect().left;
|
||||||
|
var move_block_left = x - bar_area_left //小方块相对于父元素的left值
|
||||||
|
if (move_block_left >= barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2) {
|
||||||
|
move_block_left = barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2;
|
||||||
|
}
|
||||||
|
if (move_block_left <= 0) {
|
||||||
|
move_block_left = parseInt(parseInt(blockSize.value.width) / 2);
|
||||||
|
}
|
||||||
|
//拖动后小方块的left值
|
||||||
|
moveBlockLeft.value = (move_block_left - startLeft.value) + "px"
|
||||||
|
leftBarWidth.value = (move_block_left - startLeft.value) + "px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//鼠标松开
|
||||||
|
function end() {
|
||||||
|
endMovetime.value = +new Date();
|
||||||
|
//判断是否重合
|
||||||
|
if (status.value && isEnd.value == false) {
|
||||||
|
var moveLeftDistance = parseInt((moveBlockLeft.value || '').replace('px', ''));
|
||||||
|
moveLeftDistance = moveLeftDistance * 310/ parseInt(setSize.imgWidth)
|
||||||
|
let data = {
|
||||||
|
captchaType:captchaType.value,
|
||||||
|
"captcha_code":secretKey.value ? aesEncrypt(JSON.stringify({x:moveLeftDistance,y:5.0}),secretKey.value):JSON.stringify({x:moveLeftDistance,y:5.0}),
|
||||||
|
"captcha_key":backToken.value
|
||||||
|
}
|
||||||
|
reqCheck(data).then(res=>{
|
||||||
|
if (res.code == "200") {
|
||||||
|
moveBlockBackgroundColor.value = '#5cb85c'
|
||||||
|
leftBarBorderColor.value = '#5cb85c'
|
||||||
|
iconColor.value = '#fff'
|
||||||
|
iconClass.value = 'icon-check'
|
||||||
|
showRefresh.value = false
|
||||||
|
isEnd.value = true;
|
||||||
|
if (mode.value=='pop') {
|
||||||
|
setTimeout(()=>{
|
||||||
|
proxy.$parent.clickShow = false;
|
||||||
|
refresh();
|
||||||
|
},1500)
|
||||||
|
}
|
||||||
|
passFlag.value = true
|
||||||
|
tipWords.value = `${((endMovetime.value-startMoveTime.value)/1000).toFixed(2)}s验证成功`
|
||||||
|
var captchaVerification = secretKey.value ? aesEncrypt(backToken.value+'---'+JSON.stringify({x:moveLeftDistance,y:5.0}),secretKey.value):backToken.value+'---'+JSON.stringify({x:moveLeftDistance,y:5.0})
|
||||||
|
setTimeout(()=>{
|
||||||
|
tipWords.value = ""
|
||||||
|
proxy.$parent.closeBox();
|
||||||
|
proxy.$parent.$emit('success', {captchaVerification})
|
||||||
|
},1000)
|
||||||
|
}else{
|
||||||
|
moveBlockBackgroundColor.value = '#d9534f'
|
||||||
|
leftBarBorderColor.value = '#d9534f'
|
||||||
|
iconColor.value = '#fff'
|
||||||
|
iconClass.value = 'icon-close'
|
||||||
|
passFlag.value = false
|
||||||
|
setTimeout(function () {
|
||||||
|
refresh();
|
||||||
|
}, 1000);
|
||||||
|
proxy.$parent.$emit('error',proxy)
|
||||||
|
tipWords.value = "验证失败"
|
||||||
|
setTimeout(()=>{
|
||||||
|
tipWords.value = ""
|
||||||
|
},1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
status.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const refresh = ()=>{
|
||||||
|
showRefresh.value = true
|
||||||
|
finishText.value = ''
|
||||||
|
|
||||||
|
transitionLeft.value = 'left .3s'
|
||||||
|
moveBlockLeft.value = 0
|
||||||
|
|
||||||
|
leftBarWidth.value = undefined
|
||||||
|
transitionWidth.value = 'width .3s'
|
||||||
|
|
||||||
|
leftBarBorderColor.value = '#ddd'
|
||||||
|
moveBlockBackgroundColor.value = '#fff'
|
||||||
|
iconColor.value = '#000'
|
||||||
|
iconClass.value = 'icon-right'
|
||||||
|
isEnd.value = false
|
||||||
|
|
||||||
|
getPictrue()
|
||||||
|
setTimeout(() => {
|
||||||
|
transitionWidth.value = ''
|
||||||
|
transitionLeft.value = ''
|
||||||
|
text.value = explain.value
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求背景图片和验证图片
|
||||||
|
function getPictrue(){
|
||||||
|
let data = {
|
||||||
|
captchaType:captchaType.value
|
||||||
|
}
|
||||||
|
reqGet(data).then(res=>{
|
||||||
|
if (res.code == "200") {
|
||||||
|
backImgBase.value = res.data.originalImageBase64
|
||||||
|
blockBackImgBase.value = res.data.jigsawImageBase64
|
||||||
|
backToken.value = res.data.token
|
||||||
|
secretKey.value = res.data.secretKey
|
||||||
|
}else{
|
||||||
|
tipWords.value = res.msg;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
secretKey, //后端返回的ase加密秘钥
|
||||||
|
passFlag, //是否通过的标识
|
||||||
|
backImgBase, //验证码背景图片
|
||||||
|
blockBackImgBase, //验证滑块的背景图片
|
||||||
|
backToken, //后端返回的唯一token值
|
||||||
|
startMoveTime, //移动开始的时间
|
||||||
|
endMovetime, //移动结束的时间
|
||||||
|
tipsBackColor, //提示词的背景颜色
|
||||||
|
tipWords,
|
||||||
|
text,
|
||||||
|
finishText,
|
||||||
|
setSize,
|
||||||
|
top,
|
||||||
|
left,
|
||||||
|
moveBlockLeft,
|
||||||
|
leftBarWidth,
|
||||||
|
// 移动中样式
|
||||||
|
moveBlockBackgroundColor,
|
||||||
|
leftBarBorderColor,
|
||||||
|
iconColor,
|
||||||
|
iconClass,
|
||||||
|
status, //鼠标状态
|
||||||
|
isEnd, //是够验证完成
|
||||||
|
showRefresh,
|
||||||
|
transitionLeft,
|
||||||
|
transitionWidth,
|
||||||
|
barArea,
|
||||||
|
refresh,
|
||||||
|
start
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
31
admin/src/components/verifition/api/index.js
Normal file
31
admin/src/components/verifition/api/index.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* 此处可直接引用自己项目封装好的 axios 配合后端联调
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import request from "./../utils/axios" //组件内部封装的axios
|
||||||
|
// import request from "@/api/axios.js" //调用项目封装的axios
|
||||||
|
|
||||||
|
//获取验证图片 以及token
|
||||||
|
export function reqGet(data) {
|
||||||
|
return request.get('/captcha/create',{params:{...data}});
|
||||||
|
|
||||||
|
// return request({
|
||||||
|
// url: '/captcha/create',
|
||||||
|
// method: 'get',
|
||||||
|
// data
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
//滑动或者点选验证
|
||||||
|
export function reqCheck(data) {
|
||||||
|
return request.get('/captcha/check',{params:{...data}});
|
||||||
|
|
||||||
|
// return request({
|
||||||
|
// url: '/captcha/check',
|
||||||
|
// method: 'post',
|
||||||
|
// data
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
11
admin/src/components/verifition/utils/ase.js
Normal file
11
admin/src/components/verifition/utils/ase.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
/**
|
||||||
|
* @word 要加密的内容
|
||||||
|
* @keyWord String 服务器随机返回的关键字
|
||||||
|
* */
|
||||||
|
export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
|
||||||
|
var key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||||
|
var srcs = CryptoJS.enc.Utf8.parse(word);
|
||||||
|
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
|
||||||
|
return encrypted.toString();
|
||||||
|
}
|
||||||
30
admin/src/components/verifition/utils/axios.js
Normal file
30
admin/src/components/verifition/utils/axios.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_URL;
|
||||||
|
|
||||||
|
const service = axios.create({
|
||||||
|
timeout: 40000,
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
'Content-Type': 'application/json; charset=UTF-8'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
service.interceptors.request.use(
|
||||||
|
config => {
|
||||||
|
return config
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// response interceptor
|
||||||
|
service.interceptors.response.use(
|
||||||
|
response => {
|
||||||
|
const res = response.data;
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
}
|
||||||
|
)
|
||||||
|
export default service
|
||||||
35
admin/src/components/verifition/utils/util.js
Normal file
35
admin/src/components/verifition/utils/util.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
export function resetSize(vm) {
|
||||||
|
var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度
|
||||||
|
|
||||||
|
var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth
|
||||||
|
var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight
|
||||||
|
if (vm.imgSize.width.indexOf('%') != -1) {
|
||||||
|
img_width = parseInt(vm.imgSize.width) / 100 * parentWidth + 'px'
|
||||||
|
} else {
|
||||||
|
img_width = vm.imgSize.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm.imgSize.height.indexOf('%') != -1) {
|
||||||
|
img_height = parseInt(vm.imgSize.height) / 100 * parentHeight + 'px'
|
||||||
|
} else {
|
||||||
|
img_height = vm.imgSize.height
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm.barSize.width.indexOf('%') != -1) {
|
||||||
|
bar_width = parseInt(vm.barSize.width) / 100 * parentWidth + 'px'
|
||||||
|
} else {
|
||||||
|
bar_width = vm.barSize.width
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm.barSize.height.indexOf('%') != -1) {
|
||||||
|
bar_height = parseInt(vm.barSize.height) / 100 * parentHeight + 'px'
|
||||||
|
} else {
|
||||||
|
bar_height = vm.barSize.height
|
||||||
|
}
|
||||||
|
|
||||||
|
return {imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
|
||||||
|
export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']
|
||||||
|
export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']
|
||||||
@ -9,6 +9,7 @@ let i18n = createI18n({
|
|||||||
datetimeFormats: {},
|
datetimeFormats: {},
|
||||||
numberFormats: {},
|
numberFormats: {},
|
||||||
globalInjection: true, //是否全局注入
|
globalInjection: true, //是否全局注入
|
||||||
|
silentTranslationWarn: true,
|
||||||
messages: {
|
messages: {
|
||||||
"zh-cn": zhCn,
|
"zh-cn": zhCn,
|
||||||
en
|
en
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import useAppStore from '@/stores/modules/app'
|
|||||||
|
|
||||||
const t = (message: string) => {
|
const t = (message: string) => {
|
||||||
const path = useAppStore().route
|
const path = useAppStore().route
|
||||||
const file = path == '/' ? 'index' : path.replace('/', '').replaceAll('/', '.')
|
const file = path == '/' ? 'index' : path.replace(/^(\/admin\/|\/site\/|\/)/, '').replaceAll('/', '.')
|
||||||
const key = `${file}.${message}`
|
const key = `${file}.${message}`
|
||||||
return i18n.global.t(key) != key ? i18n.global.t(key) : i18n.global.t(message)
|
return i18n.global.t(key) != key ? i18n.global.t(key) : i18n.global.t(message)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,12 +30,7 @@ class Language {
|
|||||||
*/
|
*/
|
||||||
public async loadLocaleMessages(path: string, locale: string) {
|
public async loadLocaleMessages(path: string, locale: string) {
|
||||||
try {
|
try {
|
||||||
const file = path == '/' ? 'index' : path.replace('/', '').replaceAll('/', '.')
|
const file = path == '/' ? 'index' : path.replace(/^(\/admin\/|\/site\/|\/)/, '').replaceAll('/', '.')
|
||||||
|
|
||||||
if (this.loadLocale.includes(`${locale}/${file}`)) {
|
|
||||||
return nextTick()
|
|
||||||
}
|
|
||||||
this.loadLocale.push(`${locale}/${file}`)
|
|
||||||
|
|
||||||
// 引入语言包文件
|
// 引入语言包文件
|
||||||
const messages = await import(`./${locale}/${file}.json`)
|
const messages = await import(`./${locale}/${file}.json`)
|
||||||
@ -48,7 +43,8 @@ class Language {
|
|||||||
this.i18n.global.mergeLocaleMessage(locale, data)
|
this.i18n.global.mergeLocaleMessage(locale, data)
|
||||||
this.setI18nLanguage(locale)
|
this.setI18nLanguage(locale)
|
||||||
return nextTick()
|
return nextTick()
|
||||||
} catch {
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
this.setI18nLanguage(locale)
|
this.setI18nLanguage(locale)
|
||||||
return nextTick()
|
return nextTick()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,5 +31,6 @@
|
|||||||
"isShowNumber":"是否显示必须是数字",
|
"isShowNumber":"是否显示必须是数字",
|
||||||
"isShowBetween":"是否显示只能是0或者1",
|
"isShowBetween":"是否显示只能是0或者1",
|
||||||
"sortNumber":"排序号必须是数字",
|
"sortNumber":"排序号必须是数字",
|
||||||
"sortBetween":"排序号需要在0-10000之间"
|
"sortBetween":"排序号需要在0-10000之间",
|
||||||
|
"articleNull":"未读取到文章信息!"
|
||||||
}
|
}
|
||||||
25
admin/src/lang/zh-cn/auth.menu.json
Normal file
25
admin/src/lang/zh-cn/auth.menu.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"menuName": "菜单名称",
|
||||||
|
"menuType": "类型",
|
||||||
|
"authId": "权限标识",
|
||||||
|
"menuTypeDir": "目录",
|
||||||
|
"menuTypeMenu": "菜单",
|
||||||
|
"menuTypeButton": "按钮",
|
||||||
|
"menuDeleteTips": "确定要删除该菜单吗?",
|
||||||
|
"addMenu": "添加菜单",
|
||||||
|
"updateMenu": "编辑菜单",
|
||||||
|
"routePath": "路由路径",
|
||||||
|
"viewPath": "组件路径",
|
||||||
|
"parentMenu": "父级菜单",
|
||||||
|
"menuIcon": "菜单图标",
|
||||||
|
"sort":"权重",
|
||||||
|
"menuKey":"菜单标识",
|
||||||
|
"menuNamePlaceholder": "请输入菜单名称",
|
||||||
|
"menuKeyPlaceholder": "请输入菜单标识",
|
||||||
|
"menuKeyValidata":"菜单标识只能使用字母数字下划线并且开头不能为数字",
|
||||||
|
"routePathPlaceholder": "请输入路由路径",
|
||||||
|
"viewPathPlaceholder": "请输入组件路径",
|
||||||
|
"authIdPlaceholder": "请输入权限标识",
|
||||||
|
"selectIconPlaceholder": "请选择菜单图标",
|
||||||
|
"topLevel": "顶级"
|
||||||
|
}
|
||||||
@ -15,6 +15,8 @@
|
|||||||
"lock":"锁定",
|
"lock":"锁定",
|
||||||
"unlock":"解锁",
|
"unlock":"解锁",
|
||||||
"status":"用户状态",
|
"status":"用户状态",
|
||||||
|
"statusUnlock":"正常",
|
||||||
|
"statusLock":"锁定",
|
||||||
"userUnlockTips":"确定要解锁该管理员吗?",
|
"userUnlockTips":"确定要解锁该管理员吗?",
|
||||||
"userLockTips":"确定要锁定该管理员吗?"
|
"userLockTips":"确定要锁定该管理员吗?"
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"isOpen": "是否开启",
|
"isOpen": "是否开启",
|
||||||
"h5DomainName": "h5域名",
|
"h5DomainName": "h5域名",
|
||||||
|
"clickVisit": "点击访问",
|
||||||
"H5Info": "h5配置信息"
|
"H5Info": "h5配置信息"
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"pcInfo": "电脑端信息",
|
"pcInfo": "电脑端信息",
|
||||||
"preview": "预览图"
|
"preview": "预览图",
|
||||||
|
"copy": "复制",
|
||||||
|
"clickVisit": "点击访问",
|
||||||
|
"PCDomainName": "pc域名"
|
||||||
}
|
}
|
||||||
@ -34,6 +34,7 @@
|
|||||||
"yes": "是",
|
"yes": "是",
|
||||||
"no": "否",
|
"no": "否",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
|
"complete": "完成",
|
||||||
"copySuccess": "复制成功",
|
"copySuccess": "复制成功",
|
||||||
"notSupportCopy": "浏览器不支持一键复制,请手动进行复制",
|
"notSupportCopy": "浏览器不支持一键复制,请手动进行复制",
|
||||||
"selectPlaceholder": "全部",
|
"selectPlaceholder": "全部",
|
||||||
@ -69,7 +70,10 @@
|
|||||||
"layoutSetting": "主题设置",
|
"layoutSetting": "主题设置",
|
||||||
"darkMode": "黑暗模式",
|
"darkMode": "黑暗模式",
|
||||||
"sidebarMode": "主题风格",
|
"sidebarMode": "主题风格",
|
||||||
"themeColor": "主题颜色"
|
"themeColor": "主题颜色",
|
||||||
|
"detectionLoginOperation": "确定",
|
||||||
|
"detectionLoginContent": "已检测到有其他账号登录,需要刷新后才能继续操作。",
|
||||||
|
"detectionLoginTip": "提示"
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"unknownError": "未知错误",
|
"unknownError": "未知错误",
|
||||||
|
|||||||
39
admin/src/lang/zh-cn/finance.cash_out.json
Normal file
39
admin/src/lang/zh-cn/finance.cash_out.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"orderNo":"订单编号",
|
||||||
|
"orderStatus":"订单状态",
|
||||||
|
"orderNoPlaceholder":"请输入订单编号",
|
||||||
|
"createTime":"创建时间",
|
||||||
|
"rechargeMoney":"充值金额",
|
||||||
|
"orderMoney":"订单金额",
|
||||||
|
"member":"买家",
|
||||||
|
"orderFromName":"订单来源",
|
||||||
|
"payTypeName":"支付方式",
|
||||||
|
"startDate":"开始时间",
|
||||||
|
"endDate":"结束时间",
|
||||||
|
"namePlaceholder":"请选择",
|
||||||
|
"applyTime":"申请时间",
|
||||||
|
"cashOutStatus":"提现状态",
|
||||||
|
"actualTransferAmount":"实际转账金额",
|
||||||
|
"cashOutCommission":"提现手续费",
|
||||||
|
"applicationForWithdrawalAmount":"申请提现金额",
|
||||||
|
"cashOutMethod":"提现方式",
|
||||||
|
"cashOutAccountType":"会员账户",
|
||||||
|
"memberInfo":"会员信息",
|
||||||
|
"toBeReviewed":"待审核",
|
||||||
|
"toBeTransferred":"待转账",
|
||||||
|
"transferred":"已转账",
|
||||||
|
"turnDown":"拒绝",
|
||||||
|
"transfer": "转账",
|
||||||
|
"detail": "详情",
|
||||||
|
"auditFailure": "审核失败",
|
||||||
|
"successfulAudit": "审核成功",
|
||||||
|
"rejectionAudit": "拒绝审核",
|
||||||
|
"reasonsRefusal": "拒绝理由",
|
||||||
|
"reasonsRefusalPlaceholder": "请输入拒绝理由",
|
||||||
|
"isTransfer": "是否确认转账",
|
||||||
|
"nickname":"会员名称",
|
||||||
|
"headimg":"会员头像",
|
||||||
|
"cashOutDetail":"提现详情",
|
||||||
|
"cashOutMoney": "转账金额"
|
||||||
|
|
||||||
|
}
|
||||||
@ -10,5 +10,9 @@
|
|||||||
"payTypeName":"支付方式",
|
"payTypeName":"支付方式",
|
||||||
"startDate":"开始时间",
|
"startDate":"开始时间",
|
||||||
"endDate":"结束时间",
|
"endDate":"结束时间",
|
||||||
"namePlaceholder":"请选择"
|
"namePlaceholder":"请选择",
|
||||||
|
"refundBtn":"退款",
|
||||||
|
"refundContent":"是否确认退款"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
14
admin/src/lang/zh-cn/finance.refund.json
Normal file
14
admin/src/lang/zh-cn/finance.refund.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"refundNumber":"退款单号",
|
||||||
|
"userInfo":"用户信息",
|
||||||
|
"sourceNumber":"来源单号",
|
||||||
|
"refundAmount":"退款金额",
|
||||||
|
"refundTime":"退款时间",
|
||||||
|
"detail": "详情",
|
||||||
|
"statusName": "状态",
|
||||||
|
"memberInfo": "会员",
|
||||||
|
"refundSource": "退款来源",
|
||||||
|
"startDate":"开始时间",
|
||||||
|
"endDate":"结束时间",
|
||||||
|
"refundStatus": "退款状态"
|
||||||
|
}
|
||||||
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"orderNo":"订单编号",
|
|
||||||
"orderStatus":"订单状态",
|
|
||||||
"orderNoPlaceholder":"请输入订单编号",
|
|
||||||
"createTime":"创建时间",
|
|
||||||
"rechargeMoney":"充值金额",
|
|
||||||
"orderMoney":"订单金额",
|
|
||||||
"member":"买家",
|
|
||||||
"orderFromName":"订单来源",
|
|
||||||
"payTypeName":"支付方式",
|
|
||||||
"startDate":"开始时间",
|
|
||||||
"endDate":"结束时间",
|
|
||||||
"namePlaceholder":"请选择",
|
|
||||||
"applyTime":"申请时间",
|
|
||||||
"withdrawalStatus":"提现状态",
|
|
||||||
"actualTransferAmount":"实际转账金额",
|
|
||||||
"withdrawalCommission":"提现手续费",
|
|
||||||
"applicationForWithdrawalAmount":"申请提现金额",
|
|
||||||
"withdrawalMethod":"提现方式",
|
|
||||||
"memberInfo":"会员信息",
|
|
||||||
"toBeTransferred":"待转账",
|
|
||||||
"transferred":"已转账",
|
|
||||||
"turnDown":"拒绝"
|
|
||||||
}
|
|
||||||
@ -1,9 +1,10 @@
|
|||||||
{
|
{
|
||||||
|
"dataSummarize": "数据概括",
|
||||||
"todayData": "今日数据",
|
"todayData": "今日数据",
|
||||||
"memberNumb": "会员数量",
|
"memberNumb": "新增会员数",
|
||||||
"orderMoney": "订单金额",
|
"orderMoney": "订单金额",
|
||||||
"numberOfSites": "站点数量",
|
"numberOfSites": "站点数量",
|
||||||
"numberOfVisitors": "访客数量",
|
"numberOfVisitors": "今日访客数",
|
||||||
"commonlyUsedFunction": "常用功能",
|
"commonlyUsedFunction": "常用功能",
|
||||||
"articleList": "文章列表",
|
"articleList": "文章列表",
|
||||||
"memberManagement": "会员管理",
|
"memberManagement": "会员管理",
|
||||||
@ -20,7 +21,7 @@
|
|||||||
"versions": "当前版本",
|
"versions": "当前版本",
|
||||||
"frame": "基于框架",
|
"frame": "基于框架",
|
||||||
"channel": "获取渠道",
|
"channel": "获取渠道",
|
||||||
"serviceSupport": "服务支持",
|
"serviceSupport": "官方客服",
|
||||||
"officialWbsite": "官网",
|
"officialWbsite": "官网",
|
||||||
"pageView": "访问量",
|
"pageView": "访问量",
|
||||||
"siteInfo":"站点信息",
|
"siteInfo":"站点信息",
|
||||||
@ -28,5 +29,17 @@
|
|||||||
"groupName":"站点套餐",
|
"groupName":"站点套餐",
|
||||||
"expireTime":"过期时间",
|
"expireTime":"过期时间",
|
||||||
"permanent":"永久",
|
"permanent":"永久",
|
||||||
"statusName":"站点状态"
|
"statusName":"站点状态",
|
||||||
|
"newSiteSum": "新增站点数",
|
||||||
|
"total": "总计",
|
||||||
|
"newMemberSum": "新增用户数",
|
||||||
|
"siteList": "站点列表",
|
||||||
|
"sitePackage": "站点套餐",
|
||||||
|
"newSite": "新增站点",
|
||||||
|
"appMarketplace": "应用市场",
|
||||||
|
"siteDistribution": "站点分布",
|
||||||
|
"siteSum": "站点数",
|
||||||
|
"memberSum": "用户数",
|
||||||
|
"appSum": "应用数",
|
||||||
|
"installAppSun": "安装应用数"
|
||||||
}
|
}
|
||||||
@ -1,9 +1,12 @@
|
|||||||
{
|
{
|
||||||
"siteTitle": "Niucloud Admin",
|
"siteTitle": "NIUCLOUD-ADMIN",
|
||||||
"siteDesc": "基于thinkphp6+elementplus+typescript等技术的多端saas通用管理框架,采用restful的api接口设计,前后端完全分离,同时支持多语言开发。",
|
"siteDesc": "基于thinkphp6+elementplus+typescript等技术的多端saas通用管理框架,采用restful的api接口设计,前后端完全分离,同时支持多语言开发。",
|
||||||
"logging": "登录中",
|
"logging": "登录中",
|
||||||
"platform": "管理端",
|
"platform": "管理端",
|
||||||
"login" : "登录",
|
"login" : "登录",
|
||||||
|
"siteLogin": "站点登录",
|
||||||
|
"adminLogin": "平台登录",
|
||||||
"userPlaceholder": "请输入您的账号",
|
"userPlaceholder": "请输入您的账号",
|
||||||
"passwordPlaceholder": "请输入您的密码"
|
"passwordPlaceholder": "请输入您的密码",
|
||||||
|
"manageAdminFramework": "管理系统后台框架"
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"accountData":"金额",
|
"accountData":"金额",
|
||||||
"fromType":"变动类型",
|
"fromType":"来源/用途",
|
||||||
"balanceInfo":"余额变动详情",
|
"balanceInfo":"余额变动详情",
|
||||||
"memo":"备注",
|
"memo":"备注",
|
||||||
"mobile":"手机号码",
|
"mobile":"手机号码",
|
||||||
@ -20,5 +20,8 @@
|
|||||||
"memoPlaceholder":"请输入备注信息",
|
"memoPlaceholder":"请输入备注信息",
|
||||||
"addMemberAccountLog":"添加会员账单表",
|
"addMemberAccountLog":"添加会员账单表",
|
||||||
"updateMemberAccountLog":"编辑会员账单表",
|
"updateMemberAccountLog":"编辑会员账单表",
|
||||||
"member_account_logDeleteTips":"确定要删除该会员账单表吗?"
|
"memberAccountLogDeleteTips":"确定要删除该会员账单表吗?",
|
||||||
|
"balance": "不可提现余额",
|
||||||
|
"money":"可提现余额",
|
||||||
|
"balanceType":"账户类型"
|
||||||
}
|
}
|
||||||
24
admin/src/lang/zh-cn/member.commission.json
Normal file
24
admin/src/lang/zh-cn/member.commission.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"accountData":"金额",
|
||||||
|
"fromType":"来源/用途",
|
||||||
|
"moneyInfo":"佣金变动详情",
|
||||||
|
"memo":"备注",
|
||||||
|
"mobile":"手机号码",
|
||||||
|
"nickName":"会员信息",
|
||||||
|
"headimg":"会员头像",
|
||||||
|
"createTime":"产生时间",
|
||||||
|
"startDate":"开始时间",
|
||||||
|
"endDate":"结束时间",
|
||||||
|
"searchMember":"昵称/手机号",
|
||||||
|
"searchMemberPlaceholder":"请输入会员昵称/手机号码",
|
||||||
|
"memberIdPlaceholder":"请输入会员id",
|
||||||
|
"accountTypePlaceholder":"请输入账户类型",
|
||||||
|
"accountDataPlaceholder":"请输入账户数据",
|
||||||
|
"fromTypePlaceholder":"请输入来源类型",
|
||||||
|
"relatedIdPlaceholder":"请输入关联Id",
|
||||||
|
"createTimePlaceholder":"请输入创建时间",
|
||||||
|
"memoPlaceholder":"请输入备注信息",
|
||||||
|
"addMemberAccountLog":"添加会员账单表",
|
||||||
|
"updateMemberAccountLog":"编辑会员账单表",
|
||||||
|
"member_account_logDeleteTips":"确定要删除该会员账单表吗?"
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@
|
|||||||
"wxOpenid": "微信小程openid",
|
"wxOpenid": "微信小程openid",
|
||||||
"memberLabel": "会员标签",
|
"memberLabel": "会员标签",
|
||||||
"memberLabelPlaceholder": "请选择会员标签",
|
"memberLabelPlaceholder": "请选择会员标签",
|
||||||
|
"nickNamePlaceholder": "请输入会员名称",
|
||||||
"updateMember": "编辑会员信息",
|
"updateMember": "编辑会员信息",
|
||||||
"notAvailable":"暂无",
|
"notAvailable":"暂无",
|
||||||
"girlSex":"女",
|
"girlSex":"女",
|
||||||
@ -42,6 +43,8 @@
|
|||||||
"mobile":"手机号",
|
"mobile":"手机号",
|
||||||
"detail":"详情",
|
"detail":"详情",
|
||||||
"accumulative":"累计",
|
"accumulative":"累计",
|
||||||
"looseChange":"零钱",
|
"money":"可提现余额",
|
||||||
"adjustPoint":"调整积分"
|
"adjustPoint":"调整积分",
|
||||||
|
"commission":"佣金",
|
||||||
|
"memberNull":"未读取到会员详情信息"
|
||||||
}
|
}
|
||||||
@ -12,6 +12,6 @@
|
|||||||
"updateMemberLabel":"编辑会员标签",
|
"updateMemberLabel":"编辑会员标签",
|
||||||
"sortVerifyOne":"排序要大于零",
|
"sortVerifyOne":"排序要大于零",
|
||||||
"sortVerifyTwo":"排序不能是小数",
|
"sortVerifyTwo":"排序不能是小数",
|
||||||
"member_labelDeleteTips":"确定要删除该会员标签吗?"
|
"memberLabelDeleteTips":"确定要删除该会员标签吗?"
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"registerType":"注册方式",
|
"registerChannel":"注册来源",
|
||||||
"nickname":"会员名称",
|
"nickname":"会员名称",
|
||||||
"mobile":"手机号",
|
"mobile":"手机号",
|
||||||
"createTime":"注册时间",
|
"createTime":"注册时间",
|
||||||
"lastVisitTime":"最后登录时间",
|
"lastVisitTime":"最后访问时间",
|
||||||
"addMember":"添加会员",
|
"addMember":"添加会员",
|
||||||
"updateMember":"编辑会员",
|
"updateMember":"编辑会员",
|
||||||
"nickNamePlaceholder":"请输入会员名称",
|
"nickNamePlaceholder":"请输入会员名称",
|
||||||
@ -39,9 +39,11 @@
|
|||||||
"doubleCipherHint": "输入的两次密码不一致",
|
"doubleCipherHint": "输入的两次密码不一致",
|
||||||
"mobileHint": "请输入正确的手机号!",
|
"mobileHint": "请输入正确的手机号!",
|
||||||
"lable": "标签",
|
"lable": "标签",
|
||||||
"setLable": "设置标签",
|
"setLable": "标签",
|
||||||
"notAvailable": "暂无",
|
"notAvailable": "暂无",
|
||||||
"memberLabelPlaceholder": "请选择会员标签",
|
"memberLabelPlaceholder": "请选择会员标签",
|
||||||
"memberInfo":"会员信息",
|
"memberInfo":"会员信息",
|
||||||
"memberInfoPlaceholder":"请输入会员名称/会员昵称/手机号"
|
"memberInfoPlaceholder":"请输入会员名称/会员昵称/手机号",
|
||||||
|
"lock": "锁定",
|
||||||
|
"scrubLock": "取消锁定"
|
||||||
}
|
}
|
||||||
7
admin/src/lang/zh-cn/setting.adminlogin.json
Normal file
7
admin/src/lang/zh-cn/setting.adminlogin.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"isCaptcha": "是否启用验证码",
|
||||||
|
"bgImg": "背景图片",
|
||||||
|
"admin": "平台端",
|
||||||
|
"isBgImgTip": "建议上传尺寸为450*400px",
|
||||||
|
"site": "站点端"
|
||||||
|
}
|
||||||
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"siteId":"站点id",
|
"siteId":"站点id",
|
||||||
"messageKey":"消息模板",
|
"noticeKey":"消息模板",
|
||||||
"messageType":"消息类型",
|
"noticeType":"消息类型",
|
||||||
"messageInfo":"消息详情",
|
"noticeInfo":"消息详情",
|
||||||
"uid":"通知的用户id",
|
"uid":"通知的用户id",
|
||||||
"memberId":"消息的会员id",
|
"memberId":"消息的会员id",
|
||||||
"nickname":"接收会员",
|
"nickname":"接收会员",
|
||||||
"receiver":"手机/OPENID",
|
"receiver":"手机/OPENID",
|
||||||
"messageData":"消息内容",
|
"noticeData":"消息内容",
|
||||||
"isClick":"点击次数",
|
"isClick":"点击次数",
|
||||||
"searchReceiver":"接收人",
|
"searchReceiver":"接收人",
|
||||||
"isVisit":"访问次数",
|
"isVisit":"访问次数",
|
||||||
@ -17,16 +17,16 @@
|
|||||||
"sms":"短信",
|
"sms":"短信",
|
||||||
"weapp":"微信小程序",
|
"weapp":"微信小程序",
|
||||||
"wechat":"微信公众号",
|
"wechat":"微信公众号",
|
||||||
"messageTypePlaceholder":"请选择消息类型",
|
"noticeTypePlaceholder":"请选择消息类型",
|
||||||
"uidPlaceholder":"请输入通知的用户id",
|
"uidPlaceholder":"请输入通知的用户id",
|
||||||
"memberIdPlaceholder":"请输入消息的会员id",
|
"memberIdPlaceholder":"请输入消息的会员id",
|
||||||
"nicknamePlaceholder":"请输入接收人用户昵称或姓名",
|
"nicknamePlaceholder":"请输入接收人用户昵称或姓名",
|
||||||
"receiverPlaceholder":"请输入接收人手机号/openid",
|
"receiverPlaceholder":"请输入接收人手机号/openid",
|
||||||
"messageDataPlaceholder":"请输入消息数据",
|
"noticeDataPlaceholder":"请输入消息数据",
|
||||||
"isClickPlaceholder":"请输入点击次数",
|
"isClickPlaceholder":"请输入点击次数",
|
||||||
"isVisitPlaceholder":"请输入访问次数",
|
"isVisitPlaceholder":"请输入访问次数",
|
||||||
"visitTimePlaceholder":"请输入访问时间",
|
"visitTimePlaceholder":"请输入访问时间",
|
||||||
"createTimePlaceholder":"请输入消息时间",
|
"createTimePlaceholder":"请输入消息时间",
|
||||||
"buyerMessage": "会员消息",
|
"buyerNotice": "会员消息",
|
||||||
"sellerMessage":"平台消息"
|
"sellerNotice":"平台消息"
|
||||||
}
|
}
|
||||||
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"buyerMessage": "会员消息",
|
"buyerNotice": "会员消息",
|
||||||
"sellerMessage":"平台消息",
|
"sellerNotice":"平台消息",
|
||||||
"sms":"短信",
|
"sms":"短信",
|
||||||
"weapp":"微信小程序",
|
"weapp":"微信小程序",
|
||||||
"wechat":"微信公众号",
|
"wechat":"微信公众号",
|
||||||
"messageSetting":"消息设置",
|
"noticeSetting":"消息设置",
|
||||||
"name": "模板名称",
|
"name": "模板名称",
|
||||||
"title": "场景",
|
"title": "场景",
|
||||||
"smsContent": "短信内容",
|
"smsContent": "短信内容",
|
||||||
@ -34,5 +34,20 @@
|
|||||||
"appIdTips": "支付宝分配给开发者的应用ID",
|
"appIdTips": "支付宝分配给开发者的应用ID",
|
||||||
"appPublicCertPathTips": "上传appCertPublicKey文件",
|
"appPublicCertPathTips": "上传appCertPublicKey文件",
|
||||||
"alipayPublicCertPathTips": "上传alipayCertPublicKey文件",
|
"alipayPublicCertPathTips": "上传alipayCertPublicKey文件",
|
||||||
"alipayRootCertPathTips": "上传alipayRootCert文件"
|
"alipayRootCertPathTips": "上传alipayRootCert文件",
|
||||||
|
"payType": "支付方式",
|
||||||
|
"templateName": "配置信息",
|
||||||
|
"settingDefaultPay": "设置默认支付",
|
||||||
|
"settingDefault": "设置默认",
|
||||||
|
"defaultTamplate": "请选择模板",
|
||||||
|
"isEnable": "是否启用",
|
||||||
|
"onState": "开启状态",
|
||||||
|
"configurePaymentMethod": "请先配置值该支付方式",
|
||||||
|
"enablePaymentMode": "请先开启该支付方式",
|
||||||
|
"clickConfigure": "点击配置",
|
||||||
|
"setConfig": "设置支付配置",
|
||||||
|
"open": "开启",
|
||||||
|
"notOpen": "未开启",
|
||||||
|
"cancel": "取消"
|
||||||
|
|
||||||
}
|
}
|
||||||
31
admin/src/lang/zh-cn/setting.pay.transfer.json
Normal file
31
admin/src/lang/zh-cn/setting.pay.transfer.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"wechatpay": "微信打款设置",
|
||||||
|
"alipay": "支付宝打款设置",
|
||||||
|
"mchId": "商户号",
|
||||||
|
"mchIdPlaceholder": "请输入商户号",
|
||||||
|
"mchIdTips": "微信支付商户号(MCHID)",
|
||||||
|
"mchSecretKey": "API密钥",
|
||||||
|
"mchSecretKeyPlaceholder": "请输入API密钥",
|
||||||
|
"mchSecretKeyTips": "微信支付商户API密钥(paySignKey)",
|
||||||
|
"mchSecretCert": "商户私钥",
|
||||||
|
"mchSecretCertPlaceholder": "请上传商户私钥",
|
||||||
|
"mchSecretCertTips": "微信支付API证书(apiclient_key.pem)",
|
||||||
|
"mchPublicCertPath": "商户公钥",
|
||||||
|
"mchPublicCertPathPlaceholder": "请上传商户公钥",
|
||||||
|
"mchPublicCertPathTips": "微信支付API证书(apiclient_cert.pem)",
|
||||||
|
"appId": "app_id",
|
||||||
|
"appIdPlaceholder": "请输入app_id",
|
||||||
|
"appSecretCert": "应用私钥",
|
||||||
|
"appSecretCertPlaceholder": "请输入应用私钥",
|
||||||
|
"appPublicCertPath": "应用公钥",
|
||||||
|
"appPublicCertPathPlaceholder": "请上传应用公钥",
|
||||||
|
"alipayPublicCertPath": "支付宝公钥",
|
||||||
|
"alipayPublicCertPathPlaceholder": "请上传支付宝公钥",
|
||||||
|
"alipayRootCertPath": "支付宝根证书",
|
||||||
|
"alipayRootCertPathPlaceholder": "请上传支付宝根证书",
|
||||||
|
"appIdTips": "支付宝分配给开发者的应用ID",
|
||||||
|
"appPublicCertPathTips": "上传appCertPublicKey文件",
|
||||||
|
"alipayPublicCertPathTips": "上传alipayCertPublicKey文件",
|
||||||
|
"alipayRootCertPathTips": "上传alipayRootCert文件",
|
||||||
|
"operationTip": "温馨提示:打款设置用于会员提现转账,发放红包等场景"
|
||||||
|
}
|
||||||
32
admin/src/lang/zh-cn/setting.sms.records.json
Normal file
32
admin/src/lang/zh-cn/setting.sms.records.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"siteId":"站点id",
|
||||||
|
"noticeKey":"消息模板",
|
||||||
|
"noticeType":"消息类型",
|
||||||
|
"noticeInfo":"消息详情",
|
||||||
|
"uid":"通知的用户id",
|
||||||
|
"memberId":"消息的会员id",
|
||||||
|
"nickname":"接收会员",
|
||||||
|
"receiver":"手机号",
|
||||||
|
"noticeData":"消息内容",
|
||||||
|
"isClick":"点击次数",
|
||||||
|
"searchReceiver":"接收人",
|
||||||
|
"isVisit":"访问次数",
|
||||||
|
"createTime":"发送时间",
|
||||||
|
"startDate":"开始时间",
|
||||||
|
"endDate":"结束时间",
|
||||||
|
"sms":"短信",
|
||||||
|
"weapp":"微信小程序",
|
||||||
|
"wechat":"微信公众号",
|
||||||
|
"noticeTypePlaceholder":"请选择消息类型",
|
||||||
|
"uidPlaceholder":"请输入通知的用户id",
|
||||||
|
"memberIdPlaceholder":"请输入消息的会员id",
|
||||||
|
"nicknamePlaceholder":"请输入接收人用户昵称或姓名",
|
||||||
|
"receiverPlaceholder":"请输入接收人手机号",
|
||||||
|
"noticeDataPlaceholder":"请输入消息数据",
|
||||||
|
"isClickPlaceholder":"请输入点击次数",
|
||||||
|
"isVisitPlaceholder":"请输入访问次数",
|
||||||
|
"visitTimePlaceholder":"请输入访问时间",
|
||||||
|
"createTimePlaceholder":"请输入消息时间",
|
||||||
|
"buyerNotice": "会员消息",
|
||||||
|
"sellerNotice":"平台消息"
|
||||||
|
}
|
||||||
@ -3,18 +3,18 @@
|
|||||||
"updateTime": "修改时间",
|
"updateTime": "修改时间",
|
||||||
"createTime": "创建时间",
|
"createTime": "创建时间",
|
||||||
"groupName": "套餐名称",
|
"groupName": "套餐名称",
|
||||||
"groupDesc": "套餐介绍",
|
"groupDesc": "套餐说明",
|
||||||
"groupRoles": "套餐权限",
|
"groupRoles": "套餐权限",
|
||||||
"groupDeleteTips": "确定要删除该套餐吗?",
|
"groupDeleteTips": "确定要删除该套餐吗?",
|
||||||
"groupNamePlaceholder": "请输入套餐名称",
|
"groupNamePlaceholder": "请输入套餐名称",
|
||||||
"groupDescPlaceholder": "请输入套餐介绍",
|
"groupDescPlaceholder": "请输入套餐说明",
|
||||||
"groupRolesPlaceholder": "请选择套餐权限",
|
"groupRolesPlaceholder": "请选择套餐权限",
|
||||||
"groupPlaceholder": "请选择权限",
|
"groupPlaceholder": "请选择权限",
|
||||||
"permission": "权限",
|
"permission": "权限",
|
||||||
"updateGroup":"编辑套餐",
|
"updateGroup":"编辑套餐",
|
||||||
"addGroup":"添加套餐",
|
"addGroup":"添加套餐",
|
||||||
"checkStrictly": "父子级不关联",
|
"checkStrictly": "父子级不关联",
|
||||||
"remark": "备注",
|
"remark": "套餐说明",
|
||||||
"reset": "重置",
|
"reset": "重置",
|
||||||
"search": "搜索"
|
"search": "搜索"
|
||||||
}
|
}
|
||||||
@ -5,7 +5,7 @@
|
|||||||
"status":"状态",
|
"status":"状态",
|
||||||
"businessHours":"营业时间",
|
"businessHours":"营业时间",
|
||||||
"createTime":"创建时间",
|
"createTime":"创建时间",
|
||||||
"expireTime":"过期时间",
|
"expireTime":"到期时间",
|
||||||
"siteNamePlaceholder":"请输入站点名称",
|
"siteNamePlaceholder":"请输入站点名称",
|
||||||
"createTimePlaceholder":"请输入创建时间",
|
"createTimePlaceholder":"请输入创建时间",
|
||||||
"addSite":"添加站点",
|
"addSite":"添加站点",
|
||||||
@ -24,5 +24,7 @@
|
|||||||
"confirmPasswordPlaceholder": "请再次确认密码",
|
"confirmPasswordPlaceholder": "请再次确认密码",
|
||||||
"userRealNamePlaceholder": "请输入名称",
|
"userRealNamePlaceholder": "请输入名称",
|
||||||
"expireTimePlaceholder":"请选择到期时间",
|
"expireTimePlaceholder":"请选择到期时间",
|
||||||
"confirmPasswordError": "两次输入的密码不一致"
|
"confirmPasswordError": "两次输入的密码不一致",
|
||||||
|
"operationTip": "温馨提示:站点登录页面"
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"todayData": "今日数据",
|
"todayData": "今日数据",
|
||||||
"memberNumb": "会员数量",
|
"memberNumb": "新增会员数",
|
||||||
"orderMoney": "订单金额",
|
"orderMoney": "订单金额",
|
||||||
"numberOfSites": "站点数量",
|
"numberOfSites": "站点数量",
|
||||||
"numberOfVisitors": "访客数量",
|
"numberOfVisitors": "今日访客数",
|
||||||
"commonlyUsedFunction": "常用功能",
|
"commonlyUsedFunction": "常用功能",
|
||||||
"articleList": "文章列表",
|
"articleList": "文章列表",
|
||||||
"memberManagement": "会员管理",
|
"memberManagement": "会员管理",
|
||||||
|
|||||||
@ -1,3 +1,12 @@
|
|||||||
{
|
{
|
||||||
"content":"功能正在开发,请敬请期待..."
|
"noPlug":"暂无插件",
|
||||||
|
"install":"安装",
|
||||||
|
"unload":"卸载",
|
||||||
|
"installLabel":"已安装",
|
||||||
|
"uninstalledLabel":"未安装",
|
||||||
|
"version":"版本",
|
||||||
|
"title":"名称",
|
||||||
|
"desc":"描述",
|
||||||
|
"plugDetail": "插件信息",
|
||||||
|
"author": "作者"
|
||||||
}
|
}
|
||||||
15
admin/src/lang/zh-cn/tools.detection.json
Normal file
15
admin/src/lang/zh-cn/tools.detection.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"title": "名称",
|
||||||
|
"serverInformation": "服务器信息",
|
||||||
|
"systemDemand": "系统环境要求",
|
||||||
|
"authorityStatus": "权限状态",
|
||||||
|
"name": "选项",
|
||||||
|
"demand": "要求",
|
||||||
|
"status": "状态",
|
||||||
|
"environment": "环境",
|
||||||
|
"version": "版本",
|
||||||
|
"phpType": "PHP版本",
|
||||||
|
"phpTypeValue": "大于等于8.0.0",
|
||||||
|
"mysqlType": "mysql版本",
|
||||||
|
"mysqlTypeValue": "大于等于5.7"
|
||||||
|
}
|
||||||
7
admin/src/lang/zh-cn/tools.update.json
Normal file
7
admin/src/lang/zh-cn/tools.update.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"refresh":"刷新",
|
||||||
|
"refreshMenu":"刷新菜单",
|
||||||
|
"refreshMenuDesc":"新增/修改插件菜单后,需要刷新插件菜单",
|
||||||
|
"dataCache":"数据缓存",
|
||||||
|
"dataCacheDesc":"新增/修改数据表后,需要清除数据表缓存"
|
||||||
|
}
|
||||||
@ -14,8 +14,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 返回上一页 -->
|
<!-- 返回上一页 -->
|
||||||
<div class="flex items-center cursor-pointer" v-if="appStore.pageReturn" @click="backFn">
|
<div class="flex items-center cursor-pointer" v-if="appStore.pageReturn" @click="backFn">
|
||||||
<el-icon class="mr-1"><Back /></el-icon>
|
<el-icon class="mr-1">
|
||||||
<span class="text-base mr-3">{{t('returnToPreviousPage')}}</span>
|
<Back />
|
||||||
|
</el-icon>
|
||||||
|
<span class="text-base mr-3">{{ t('returnToPreviousPage') }}</span>
|
||||||
<span class=" text-gray-300">|</span>
|
<span class=" text-gray-300">|</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 面包屑导航 -->
|
<!-- 面包屑导航 -->
|
||||||
@ -30,8 +32,9 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<div class="right-panel h-full flex items-center justify-end">
|
<div class="right-panel h-full flex items-center justify-end">
|
||||||
<!-- 预览 -->
|
<!-- 预览 只有站点时展示-->
|
||||||
<img class="w-[16px] h-[16px] mr-1" src="@/assets/images/icon_preview.png" :alt="t('preview')" :title="t('preview')">
|
<img class="w-[16px] h-[16px] mr-1" v-if="appType == 'site'" src="@/assets/images/icon_preview.png"
|
||||||
|
:alt="t('preview')" :title="t('preview')">
|
||||||
<!-- 切换语言 -->
|
<!-- 切换语言 -->
|
||||||
<div class="navbar-item flex items-center h-full cursor-pointer">
|
<div class="navbar-item flex items-center h-full cursor-pointer">
|
||||||
<switch-lang />
|
<switch-lang />
|
||||||
@ -52,6 +55,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<input type="hidden" v-model="comparisonToken">
|
||||||
|
<input type="hidden" v-model="comparisonSiteId">
|
||||||
|
|
||||||
|
<el-dialog v-model="detectionLoginDialog" :title="t('layout.detectionLoginTip')" width="30%"
|
||||||
|
:close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
|
||||||
|
<span>{{ t('layout.detectionLoginContent') }}</span>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="detectionLoginFn">{{ t('layout.detectionLoginOperation') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -65,17 +80,43 @@ import useSystemStore from '@/stores/modules/system'
|
|||||||
import useAppStore from '@/stores/modules/app'
|
import useAppStore from '@/stores/modules/app'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import storage from '@/utils/storage'
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const appType = storage.get('app_type')
|
||||||
const { toggle: toggleFullscreen, isFullscreen } = useFullscreen()
|
const { toggle: toggleFullscreen, isFullscreen } = useFullscreen()
|
||||||
const systemStore = useSystemStore()
|
const systemStore = useSystemStore()
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const screenWidth = ref(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth)
|
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(() => {
|
onMounted(() => {
|
||||||
|
// 监听窗体宽度变化
|
||||||
window.onresize = () => {
|
window.onresize = () => {
|
||||||
return (() => {
|
return (() => {
|
||||||
screenWidth.value = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
|
screenWidth.value = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
|
||||||
@ -111,15 +152,15 @@ const refreshRouter = () => {
|
|||||||
|
|
||||||
// 面包屑导航
|
// 面包屑导航
|
||||||
const breadcrumb = computed(() => {
|
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)
|
if (matched[0] && matched[0].path == '/') matched.splice(0, 1)
|
||||||
return matched
|
return matched
|
||||||
})
|
})
|
||||||
|
|
||||||
// 返回上一页
|
// 返回上一页
|
||||||
const backFn = ()=>{
|
const backFn = () => {
|
||||||
router.go(-1);
|
router.go(-1)
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -129,5 +170,4 @@ const backFn = ()=>{
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--el-bg-color-page);
|
background-color: var(--el-bg-color-page);
|
||||||
}
|
}
|
||||||
}
|
}</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,18 +1,29 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory, RouteLocationRaw } from 'vue-router'
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
import 'nprogress/nprogress.css'
|
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 { language } from '@/lang'
|
||||||
import useSystemStore from '@/stores/modules/system'
|
import useSystemStore from '@/stores/modules/system'
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import { setWindowTitle } from '@/utils/common'
|
import { setWindowTitle, getAppType, urlToRouteRaw } from '@/utils/common'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
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) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.configure({ showSpinner: false })
|
NProgress.configure({ showSpinner: false })
|
||||||
@ -23,19 +34,22 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const siteInfo = storage.get('siteInfo') || false
|
const siteInfo = storage.get('siteInfo') || false
|
||||||
let title = (to.meta?.title || '') + (siteInfo.site_name ? ('-' + siteInfo.site_name) : '')
|
let title = (to.meta?.title || '') + (siteInfo.site_name ? ('-' + siteInfo.site_name) : '')
|
||||||
|
|
||||||
// 设置网站标题
|
// 设置网站标题
|
||||||
setWindowTitle(title)
|
setWindowTitle(title)
|
||||||
// 加载语言包
|
// 加载语言包
|
||||||
await language.loadLocaleMessages(to.path, useSystemStore().lang);
|
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)) {
|
if (NO_LOGIN_ROUTES.includes(to.path)) {
|
||||||
next()
|
next()
|
||||||
} else if (userStore.token) {
|
} else if (userStore.token) {
|
||||||
// 如果已加载路由
|
// 如果已加载路由
|
||||||
if (userStore.routers.length) {
|
if (userStore.routers.length) {
|
||||||
if (to.path === '/login') {
|
if (to.path === loginPath) {
|
||||||
next('/')
|
next(`/${getAppType()}`)
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
@ -45,8 +59,17 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
|
|
||||||
// 设置首页路由
|
// 设置首页路由
|
||||||
const firstRoute = findFirstValidRoute(userStore.routers)
|
const firstRoute = findFirstValidRoute(userStore.routers)
|
||||||
INDEX_ROUTE.redirect = { name: firstRoute }
|
ROOT_ROUTER.redirect = { name: firstRoute }
|
||||||
router.addRoute(INDEX_ROUTE)
|
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 => {
|
userStore.routers.forEach(route => {
|
||||||
@ -56,25 +79,35 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
router.addRoute(DECORATE_ROUTER)
|
router.addRoute(DECORATE_ROUTER)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!route.children) {
|
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
|
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 })
|
next({ path: to.path, query: to.query, replace: true })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
userStore.logout()
|
userStore.logout()
|
||||||
next({ path: '/login', query: { redirect: to.fullPath } })
|
next({ path: loginPath, query: { redirect: to.fullPath } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (to.path === '/login') {
|
if (to.path === loginPath) {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
next({ path: '/login', query: { redirect: to.fullPath } })
|
next({ path: loginPath, query: { redirect: to.fullPath } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,25 +4,40 @@ import Decorate from '@/layout/decorate/index.vue'
|
|||||||
|
|
||||||
// 静态路由
|
// 静态路由
|
||||||
export const STATIC_ROUTES: Array<RouteRecordRaw> = [
|
export const STATIC_ROUTES: Array<RouteRecordRaw> = [
|
||||||
{
|
|
||||||
path: `${import.meta.env.BASE_URL}`,
|
|
||||||
component: Default,
|
|
||||||
name: 'root'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/:pathMatch(.*)*',
|
path: '/:pathMatch(.*)*',
|
||||||
component: () => import('@/views/error/404.vue')
|
component: () => import('@/views/error/404.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 免登录路由
|
||||||
|
export const NO_LOGIN_ROUTES: string[] = [
|
||||||
|
'/404'
|
||||||
|
]
|
||||||
|
|
||||||
|
// 根路由
|
||||||
|
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: '/403',
|
path: 'login',
|
||||||
component: () => import('@/views/error/403.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
component: () => import('@/views/login/index.vue')
|
component: () => import('@/views/login/index.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/user',
|
path: 'user',
|
||||||
component: Default,
|
component: Default,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -35,19 +50,38 @@ export const STATIC_ROUTES: Array<RouteRecordRaw> = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// 免登录路由
|
// 站点端路由
|
||||||
export const NO_LOGIN_ROUTES: string[] = [
|
export const SITE_ROUTE: RouteRecordRaw = {
|
||||||
'/403',
|
path: '/site',
|
||||||
'/404'
|
name: Symbol('site'),
|
||||||
]
|
children: [
|
||||||
|
{
|
||||||
// 首页路由
|
path: '',
|
||||||
export const INDEX_ROUTE: RouteRecordRaw = {
|
name: Symbol('siteRoot'),
|
||||||
path: '/',
|
component: Default
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'login',
|
||||||
|
component: () => import('@/views/login/index.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'user',
|
||||||
component: Default,
|
component: Default,
|
||||||
name: Symbol()
|
children: [
|
||||||
|
{
|
||||||
|
path: 'center',
|
||||||
|
meta: {
|
||||||
|
type: 1,
|
||||||
|
title: '个人中心'
|
||||||
|
},
|
||||||
|
component: () => import('@/views/index/personal.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 装修路由
|
// 装修路由
|
||||||
@ -70,7 +104,8 @@ interface Route {
|
|||||||
type: string
|
type: string
|
||||||
},
|
},
|
||||||
children?: [],
|
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 createRoute = function (route: Route, parentRoute: RouteRecordRaw | null = null): RouteRecordRaw {
|
||||||
const record: 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}`),
|
name: parentRoute ? Symbol(`${parentRoute.path}/${route.router_path}`) : Symbol(`/${route.router_path}`),
|
||||||
meta: {
|
meta: {
|
||||||
title: route.menu_name,
|
title: route.menu_name,
|
||||||
icon: route.icon,
|
icon: route.icon,
|
||||||
type: route.menu_type,
|
type: route.menu_type,
|
||||||
show: route.is_show
|
show: route.is_show,
|
||||||
|
app: route.app_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (route.menu_type == 0) {
|
if (route.menu_type == 0) {
|
||||||
|
|||||||
@ -50,20 +50,19 @@ const useDiyStore = defineStore('diy', {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
// 添加组件
|
// 添加组件
|
||||||
addComponent(data: any) {
|
addComponent(key: string, data: any) {
|
||||||
// 加载完才能添加组件
|
// 加载完才能添加组件
|
||||||
if(!this.load) return;
|
if (!this.load) return;
|
||||||
|
|
||||||
// 删除不用的字段
|
// 删除不用的字段
|
||||||
let component = cloneDeep(data);
|
let component = cloneDeep(data);
|
||||||
|
|
||||||
component.id = this.generateRandom();
|
component.id = this.generateRandom();
|
||||||
component.componentName = component.name;
|
component.componentName = key;
|
||||||
component.componentTitle = component.title;
|
component.componentTitle = component.title;
|
||||||
component.maxCount = component.max_count;
|
component.maxCount = component.max_count;
|
||||||
|
|
||||||
Object.assign(component, component.value);
|
Object.assign(component, component.value);
|
||||||
delete component.name;
|
|
||||||
delete component.title;
|
delete component.title;
|
||||||
delete component.value;
|
delete component.value;
|
||||||
delete component.type;
|
delete component.type;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { defineStore } from 'pinia'
|
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 { login, getAuthMenus } from '@/api/auth'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { formatRouters, INDEX_ROUTE } from '@/router/routers'
|
import { formatRouters } from '@/router/routers'
|
||||||
import useTabbarStore from './tabbar'
|
import useTabbarStore from './tabbar'
|
||||||
|
|
||||||
interface User {
|
interface User {
|
||||||
@ -25,9 +25,9 @@ const useSystemStore = defineStore('user', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
login(form: object) {
|
login(form: object, app_type: any) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(form)
|
login(form, app_type)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.token = res.data.token
|
this.token = res.data.token
|
||||||
this.userInfo = res.data.userinfo
|
this.userInfo = res.data.userinfo
|
||||||
@ -35,6 +35,8 @@ const useSystemStore = defineStore('user', {
|
|||||||
storage.set({ key: 'userinfo', data: res.data.userinfo })
|
storage.set({ key: 'userinfo', data: res.data.userinfo })
|
||||||
storage.set({ key: 'siteId', data: res.data.site_id })
|
storage.set({ key: 'siteId', data: res.data.site_id })
|
||||||
storage.set({ key: 'siteInfo', data: res.data.site_info })
|
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)
|
resolve(res)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -48,15 +50,10 @@ const useSystemStore = defineStore('user', {
|
|||||||
this.siteInfo = {}
|
this.siteInfo = {}
|
||||||
removeToken()
|
removeToken()
|
||||||
storage.remove(['userinfo', 'siteId', 'siteInfo'])
|
storage.remove(['userinfo', 'siteId', 'siteInfo'])
|
||||||
// 清除路由
|
|
||||||
this.routers.forEach(item => {
|
|
||||||
router.removeRoute(item.name)
|
|
||||||
})
|
|
||||||
router.removeRoute(INDEX_ROUTE.name)
|
|
||||||
this.routers = []
|
this.routers = []
|
||||||
// 清除tabbar
|
// 清除tabbar
|
||||||
useTabbarStore().clearTab()
|
useTabbarStore().clearTab()
|
||||||
router.push('/login')
|
router.push(`/${getAppType()}/login`)
|
||||||
},
|
},
|
||||||
getAuthMenus() {
|
getAuthMenus() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 3883393 */
|
font-family: "iconfont"; /* Project id 3883393 */
|
||||||
src: url('//at.alicdn.com/t/c/font_3883393_c2tb4v0fz24.woff2?t=1681374762000') format('woff2'),
|
src: url('//at.alicdn.com/t/c/font_3883393_4jlgm3tby7.woff2?t=1683947082967') format('woff2'),
|
||||||
url('//at.alicdn.com/t/c/font_3883393_c2tb4v0fz24.woff?t=1681374762000') format('woff'),
|
url('//at.alicdn.com/t/c/font_3883393_4jlgm3tby7.woff?t=1683947082967') format('woff'),
|
||||||
url('//at.alicdn.com/t/c/font_3883393_c2tb4v0fz24.ttf?t=1681374762000') format('truetype');
|
url('//at.alicdn.com/t/c/font_3883393_4jlgm3tby7.ttf?t=1683947082967') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -13,6 +13,46 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-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 {
|
.iconyingyongshichang:before {
|
||||||
content: "\e618";
|
content: "\e618";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import type {App} from 'vue'
|
import type { App } from 'vue'
|
||||||
import * as ElementPlusIconsVue from '@element-plus/icons-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 colorFunction from 'css-color-function'
|
||||||
import storage from './storage'
|
import storage from './storage'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局注册element-icon
|
* 全局注册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
|
* 设置网站 title
|
||||||
* @param value
|
* @param value
|
||||||
@ -68,7 +83,7 @@ export function getToken(): null | string {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function setToken(token: string): void {
|
export function setToken(token: string): void {
|
||||||
storage.set({key: 'token', data: token})
|
storage.set({ key: 'token', data: token })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,3 +158,19 @@ export function getWapDomain(): string {
|
|||||||
return (import.meta.env.VITE_WAP_DOMAIN || location.origin + '/wap') + (storage.get('siteId') == 1 ? '' : '/s' + storage.get('siteId'));
|
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 }
|
||||||
|
}
|
||||||
@ -52,7 +52,7 @@ class Request {
|
|||||||
this.instance.interceptors.response.use(
|
this.instance.interceptors.response.use(
|
||||||
(response: requestResponse) => {
|
(response: requestResponse) => {
|
||||||
const res = response.data
|
const res = response.data
|
||||||
if (res.code != 200) {
|
if (res.code != 1) {
|
||||||
this.handleAuthError(res.code)
|
this.handleAuthError(res.code)
|
||||||
if (response.config.showErrorMessage) ElMessage({ message: res.msg, type: 'error' })
|
if (response.config.showErrorMessage) ElMessage({ message: res.msg, type: 'error' })
|
||||||
return Promise.reject(new Error(res.msg || 'Error'))
|
return Promise.reject(new Error(res.msg || 'Error'))
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { getAppType } from './common'
|
||||||
|
|
||||||
interface setParam {
|
interface setParam {
|
||||||
key: string,
|
key: string,
|
||||||
data: any,
|
data: any,
|
||||||
@ -6,6 +8,11 @@ interface setParam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Storage {
|
class Storage {
|
||||||
|
private prefix = ''
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
this.prefix = getAppType()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置缓存
|
* 设置缓存
|
||||||
@ -13,7 +20,7 @@ class Storage {
|
|||||||
*/
|
*/
|
||||||
public set(param: setParam) {
|
public set(param: setParam) {
|
||||||
try {
|
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()
|
typeof param.success == 'function' && param.success()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
typeof param.fail == 'function' && param.fail(error)
|
typeof param.fail == 'function' && param.fail(error)
|
||||||
@ -27,7 +34,7 @@ class Storage {
|
|||||||
*/
|
*/
|
||||||
public get(key: string) {
|
public get(key: string) {
|
||||||
try {
|
try {
|
||||||
const json: any = window.localStorage.getItem(key)
|
const json: any = window.localStorage.getItem(`${this.prefix}.${key}`)
|
||||||
return JSON.parse(json)
|
return JSON.parse(json)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return null
|
return null
|
||||||
@ -39,8 +46,8 @@ class Storage {
|
|||||||
* @param key
|
* @param key
|
||||||
*/
|
*/
|
||||||
public remove(key: string | string[]) {
|
public remove(key: string | string[]) {
|
||||||
if (typeof key == 'string') window.localStorage.removeItem(key)
|
if (typeof key == 'string') window.localStorage.removeItem(`${this.prefix}.${key}`)
|
||||||
else key.forEach(item => { window.localStorage.removeItem(item) })
|
else key.forEach(item => { window.localStorage.removeItem(`${this.prefix}.${item}`) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
63
admin/src/views/app/index.vue
Normal file
63
admin/src/views/app/index.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main-container bg-[#fff] min-w-[1000px] min-h-[650px]">
|
||||||
|
<div class="pt-[1px]" v-for="(listItems, listIndex) in appManageList" :key="listIndex">
|
||||||
|
<p class="ml-4 mt-[20px] border-l-[2px] border-[#273de3] pl-4 leading-[1]">{{ listItems.name }}</p>
|
||||||
|
<div class="flex flex-wrap" v-if="isTrue == 0">
|
||||||
|
<div @click="toLink(appItems.url)" class="flex cursor-pointer ml-4 mt-[20px] w-[240px] p-[10px] border-[1px] border-[#eee] border-[solid]" v-for="(appItems, appIndex) in listItems.app_list" :key="appIndex">
|
||||||
|
<div class="flex justify-center items-center mr-[10px] min-w-[50px]">
|
||||||
|
<img v-if="appItems.icon" class="w-[50px] h-[50px]" :src="img(appItems.icon)"/>
|
||||||
|
</div>
|
||||||
|
<div class="w-[150px]">
|
||||||
|
<p class="app-text text-[14px] text-[#666]">{{ appItems.title }}</p>
|
||||||
|
<p class="app-text text-[12px] text-[#999]">{{ appItems.desc }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap" v-if="isTrue == 1">
|
||||||
|
<div @click="toLink(appItems.url)" class="cursor-pointer ml-4 mt-[20px] w-[140px] p-[10px] border-[1px] border-[#eee] border-[solid]" v-for="(appItems, appIndex) in listItems.app_list" :key="appIndex">
|
||||||
|
<div class="flex justify-center items-center">
|
||||||
|
<img v-if="appItems.cover" class="w-[110px] h-[110px]" :src="img(appItems.cover)"/>
|
||||||
|
</div>
|
||||||
|
<div class="text-center mt-2">
|
||||||
|
<p class="app-text text-[14px] text-[#666]">{{ appItems.title }}</p>
|
||||||
|
<p class="app-text text-[12px] text-[#999]">{{ appItems.desc }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { t } from '@/lang'
|
||||||
|
import { getAppMange } from '@/api/sys'
|
||||||
|
import { img } from '@/utils/common'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const appManageList = ref([])
|
||||||
|
const isTrue = ref(1)
|
||||||
|
const checkAppMange = () => {
|
||||||
|
getAppMange().then(res=>{
|
||||||
|
appManageList.value = res.data;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
checkAppMange()
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
/**
|
||||||
|
* 链接跳转
|
||||||
|
*/
|
||||||
|
const toLink = (link) => {
|
||||||
|
router.push(link)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-text {
|
||||||
|
overflow:hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-o-text-overflow:ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px"
|
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||||
:destroy-on-close="true">
|
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
v-loading="loading">
|
||||||
<el-form-item :label="t('name')" prop="name">
|
<el-form-item :label="t('name')" prop="name">
|
||||||
<el-input v-model="formData.name" clearable :placeholder="t('namePlaceholder')" class="input-width" />
|
<el-input v-model="formData.name" clearable :placeholder="t('namePlaceholder')" class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -32,9 +32,9 @@
|
|||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, reactive, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
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)
|
let showDialog = ref(false)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
@ -42,7 +42,7 @@ const loading = ref(true)
|
|||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
category_id: '',
|
category_id: '',
|
||||||
name: '',
|
name: '',
|
||||||
sort: '',
|
sort: '',
|
||||||
@ -71,7 +71,7 @@ const formRules = computed(() => {
|
|||||||
sort: [
|
sort: [
|
||||||
{
|
{
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
if(value === "" || isNaN(value)){
|
if (value === "" || isNaN(value)) {
|
||||||
callback(new Error(t('sortNumber')))
|
callback(new Error(t('sortNumber')))
|
||||||
}
|
}
|
||||||
if (parseInt(value) > 10000) {
|
if (parseInt(value) > 10000) {
|
||||||
@ -94,7 +94,7 @@ const emit = defineEmits(['complete'])
|
|||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
let save = formData.category_id ? updateArticleCategory : addArticleCategory
|
let save = formData.category_id ? editArticleCategory : addArticleCategory
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
|
v-loading="loading">
|
||||||
<el-form-item :label="t('title')" prop="title">
|
<el-form-item :label="t('title')" prop="title">
|
||||||
<el-input v-model="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width"
|
<el-input v-model="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width"
|
||||||
maxlength="20" />
|
maxlength="20" />
|
||||||
@ -62,10 +63,11 @@
|
|||||||
import { ref, reactive, computed, watch } from 'vue'
|
import { ref, reactive, computed, watch } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance, ElNotification } from 'element-plus'
|
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 { useRoute, useRouter } from 'vue-router'
|
||||||
import useTabbarStore from '@/stores/modules/tabbar'
|
import useTabbarStore from '@/stores/modules/tabbar'
|
||||||
import useAppStore from '@/stores/modules/app'
|
import useAppStore from '@/stores/modules/app'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -77,7 +79,7 @@ const appStore = useAppStore()
|
|||||||
|
|
||||||
// 页面返回按钮
|
// 页面返回按钮
|
||||||
appStore.pageReturn = true;
|
appStore.pageReturn = true;
|
||||||
watch(route, (newX,oldX) => {
|
watch(route, (newX, oldX) => {
|
||||||
appStore.pageReturn = false;
|
appStore.pageReturn = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,13 +106,20 @@ const formData: Record<string, any> = reactive({ ...initialFormData })
|
|||||||
const setFormData = async (id: number = 0) => {
|
const setFormData = async (id: number = 0) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
if(id){
|
if (id) {
|
||||||
const data = await (await getArticleInfo(id)).data
|
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) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
if (data[key] != undefined) formData[key] = data[key]
|
if (data[key] != undefined) formData[key] = data[key]
|
||||||
})
|
})
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}else{
|
} else {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,9 +148,9 @@ const formRules = computed(() => {
|
|||||||
{
|
{
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
let content = value.replace(/<[^<>]+>/g, "").replace(/ /gi, "")
|
let content = value.replace(/<[^<>]+>/g, "").replace(/ /gi, "")
|
||||||
if(!content && value.indexOf('img') === -1){
|
if (!content && value.indexOf('img') === -1) {
|
||||||
callback(new Error(t('contentPlaceholder')))
|
callback(new Error(t('contentPlaceholder')))
|
||||||
}else callback()
|
} else callback()
|
||||||
},
|
},
|
||||||
trigger: ['blur', 'change']
|
trigger: ['blur', 'change']
|
||||||
}
|
}
|
||||||
@ -155,7 +164,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const data = formData
|
const data = formData
|
||||||
const save = id ? updateArticle : addArticle
|
const save = id ? editArticle : addArticle
|
||||||
save(data).then(res => {
|
save(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
back();
|
back();
|
||||||
|
|||||||
@ -14,8 +14,8 @@
|
|||||||
<el-input v-model="articleTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
|
<el-input v-model="articleTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('categoryName')" prop="category_id">
|
<el-form-item :label="t('categoryName')" prop="category_id">
|
||||||
<el-select v-model="articleTableData.searchParam.category_id" clearable :placeholder="t('categoryIdPlaceholder')"
|
<el-select v-model="articleTableData.searchParam.category_id" clearable
|
||||||
class="input-width">
|
:placeholder="t('categoryIdPlaceholder')" class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item['name']" :value="item['category_id']" v-for="item in categoryList" />
|
<el-option :label="item['name']" :value="item['category_id']" v-for="item in categoryList" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<el-table-column prop="category_name" :label="t('categoryName')" align="center" min-width="140" />
|
<el-table-column prop="category_name" :label="t('categoryName')" align="center" min-width="140" />
|
||||||
|
|
||||||
<el-table-column prop="summary" :label="t('summary')" width="180" :show-overflow-tooltip="true"/>
|
<el-table-column prop="summary" :label="t('summary')" width="180" :show-overflow-tooltip="true" />
|
||||||
|
|
||||||
<el-table-column :label="t('isShow')" min-width="120" align="center">
|
<el-table-column :label="t('isShow')" min-width="120" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@ -83,8 +83,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, watch } from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getArticleList, deleteArticle,getArticleCategoryAll } from '@/api/article'
|
import { getArticleList, deleteArticle, getArticleCategoryAll } from '@/api/article'
|
||||||
import { img } from '@/utils/common'
|
import { img, getAppType } from '@/utils/common'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ const articleTableData = reactive({
|
|||||||
data: [],
|
data: [],
|
||||||
searchParam: {
|
searchParam: {
|
||||||
title: '',
|
title: '',
|
||||||
category_id:''
|
category_id: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const categoryList = ref([])
|
const categoryList = ref([])
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px"
|
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||||
:destroy-on-close="true">
|
<el-form :model="formData" label-width="90px" class="page-form" ref="formRef" :rules="formRules"
|
||||||
<el-form :model="formData" label-width="90px" class="page-form" ref="formRef" :rules="formRules" v-loading="loading">
|
v-loading="loading">
|
||||||
<el-form-item :label="t('menuName')" prop="menu_name">
|
<el-form-item :label="t('menuName')" prop="menu_name">
|
||||||
<el-input v-model="formData.menu_name" :placeholder="t('menuNamePlaceholder')" class="input-width" />
|
<el-input v-model="formData.menu_name" :placeholder="t('menuNamePlaceholder')" class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -98,12 +98,12 @@ import { ref, reactive, computed } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import selectMenuItem from './select-menu-item.vue'
|
import selectMenuItem from './select-menu-item.vue'
|
||||||
import { addMenu, updateMenu, getMenuInfo } from '@/api/sys'
|
import { addMenu, editMenu, getMenuInfo } from '@/api/sys'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const method = ref('post')
|
const method = ref('post')
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
let popTitle:string = '';
|
let popTitle: string = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
@ -121,8 +121,8 @@ const initialFormData = {
|
|||||||
sort: '',
|
sort: '',
|
||||||
status: 1,
|
status: 1,
|
||||||
is_show: 1,
|
is_show: 1,
|
||||||
menu_key:'',
|
menu_key: '',
|
||||||
app_type:''
|
app_type: ''
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ const formRules = computed(() => {
|
|||||||
{ required: true, message: t('menuKeyPlaceholder'), trigger: 'blur' },
|
{ required: true, message: t('menuKeyPlaceholder'), trigger: 'blur' },
|
||||||
{
|
{
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
if(!validataMenuKey(value)){
|
if (!validataMenuKey(value)) {
|
||||||
callback(new Error(t('menuKeyValidata')))
|
callback(new Error(t('menuKeyValidata')))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ const emit = defineEmits(['complete'])
|
|||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
const save = formData.id ? updateMenu : addMenu
|
const save = formData.id ? editMenu : addMenu
|
||||||
|
|
||||||
await formEl.validate(async (valid, fields) => {
|
await formEl.validate(async (valid, fields) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@ -219,7 +219,7 @@ const setFormData = async (row: any = null) => {
|
|||||||
Object.keys(formData).forEach((key: string) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
if (data[key] != undefined) formData[key] = data[key]
|
if (data[key] != undefined) formData[key] = data[key]
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
Object.keys(formData).forEach((key: string) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
if (row[key] != undefined) formData[key] = row[key]
|
if (row[key] != undefined) formData[key] = row[key]
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px"
|
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||||
:destroy-on-close="true">
|
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
v-loading="loading">
|
||||||
<el-form-item :label="t('roleName')" prop="role_name">
|
<el-form-item :label="t('roleName')" prop="role_name">
|
||||||
<el-input v-model="formData.role_name" :placeholder="t('roleNamePlaceholder')" clearable
|
<el-input v-model="formData.role_name" :placeholder="t('roleNamePlaceholder')" clearable
|
||||||
:disabled="formData.uid" class="input-width" maxlength="10" :show-word-limit="true" />
|
:disabled="formData.uid" class="input-width" maxlength="10" :show-word-limit="true" />
|
||||||
@ -42,12 +42,12 @@
|
|||||||
import { ref, reactive, computed, watch, toRaw } from 'vue'
|
import { ref, reactive, computed, watch, toRaw } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { addRole, updateRole, getRoleInfo, getSiteMenus } from '@/api/sys'
|
import { addRole, editRole, getRoleInfo, getSiteMenus } from '@/api/sys'
|
||||||
import { debounce } from '@/utils/common'
|
import { debounce } from '@/utils/common'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
let popTitle:string = '';
|
let popTitle: string = '';
|
||||||
|
|
||||||
// 获取权限数据
|
// 获取权限数据
|
||||||
const menus = ref<Record<string, any>[]>([])
|
const menus = ref<Record<string, any>[]>([])
|
||||||
@ -110,7 +110,7 @@ const emit = defineEmits(['complete'])
|
|||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
const save = formData.role_id ? updateRole : addRole
|
const save = formData.role_id ? editRole : addRole
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px"
|
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||||
:destroy-on-close="true">
|
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
v-loading="loading">
|
||||||
<el-form-item :label="t('accountNumber')" prop="username">
|
<el-form-item :label="t('accountNumber')" prop="username">
|
||||||
<el-input v-model="formData.username" :placeholder="t('accountNumberPlaceholder')" clearable
|
<el-input v-model="formData.username" :placeholder="t('accountNumberPlaceholder')" clearable
|
||||||
:disabled="formData.uid" class="input-width" maxlength="10" show-word-limit />
|
:disabled="formData.uid" class="input-width" maxlength="10" show-word-limit />
|
||||||
@ -35,8 +35,8 @@
|
|||||||
|
|
||||||
<el-form-item :label="t('status')">
|
<el-form-item :label="t('status')">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio :label="1">{{ t('statusNormal') }}</el-radio>
|
<el-radio :label="1">{{ t('statusUnlock') }}</el-radio>
|
||||||
<el-radio :label="0">{{ t('statusDeactivate') }}</el-radio>
|
<el-radio :label="0">{{ t('lock') }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -56,12 +56,12 @@
|
|||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, reactive, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { addUser, updateUser, getUserInfo } from '@/api/site'
|
import { addUser, editUser, getUserInfo } from '@/api/site'
|
||||||
import { allRole } from '@/api/sys'
|
import { allRole } from '@/api/sys'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
let popTitle:string = '';
|
let popTitle: string = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
@ -75,7 +75,7 @@ const initialFormData = {
|
|||||||
confirm_password: '',
|
confirm_password: '',
|
||||||
status: 1,
|
status: 1,
|
||||||
role_ids: [],
|
role_ids: [],
|
||||||
userrole:{}
|
userrole: {}
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -115,6 +115,9 @@ const emit = defineEmits(['complete'])
|
|||||||
const roles = ref<Record<string, any>>([])
|
const roles = ref<Record<string, any>>([])
|
||||||
allRole().then(res => {
|
allRole().then(res => {
|
||||||
roles.value = res.data
|
roles.value = res.data
|
||||||
|
roles.value.forEach(element => {
|
||||||
|
element.role_id = element.role_id.toString()
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,7 +126,7 @@ allRole().then(res => {
|
|||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
const save = formData.uid ? updateUser : addUser
|
const save = formData.uid ? editUser : addUser
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
|||||||
@ -31,9 +31,9 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('status')" min-width="120" align="center">
|
<el-table-column :label="t('status')" min-width="120" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ t('statusNormal') }}</el-tag>
|
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ t('statusUnlock') }}</el-tag>
|
||||||
<el-tag class="ml-2" type="error" v-if="row.status == 0">{{
|
<el-tag class="ml-2" type="error" v-if="row.status == 0">{{
|
||||||
t('statusDeactivate')
|
t('statusLock')
|
||||||
}}</el-tag>
|
}}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|||||||
@ -36,21 +36,21 @@
|
|||||||
|
|
||||||
<el-form-item :label="t('publicKey')">
|
<el-form-item :label="t('publicKey')">
|
||||||
<div class="input-width">
|
<div class="input-width">
|
||||||
<upload-file v-model="formData.public_key_crt" api="upload/cert/aliapp" />
|
<upload-file v-model="formData.public_key_crt" api="sys/document/aliyun" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-tip">{{ t('publicKeyTips') }}</div>
|
<div class="form-tip">{{ t('publicKeyTips') }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('alipayPublicKey')">
|
<el-form-item :label="t('alipayPublicKey')">
|
||||||
<div class="input-width">
|
<div class="input-width">
|
||||||
<upload-file v-model="formData.alipay_public_key_crt" api="upload/cert/aliapp" />
|
<upload-file v-model="formData.alipay_public_key_crt" api="sys/document/aliyun" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-tip">{{ t('alipayPublicKeyTips') }}</div>
|
<div class="form-tip">{{ t('alipayPublicKeyTips') }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('alipayWithCrt')">
|
<el-form-item :label="t('alipayWithCrt')">
|
||||||
<div class="input-width">
|
<div class="input-width">
|
||||||
<upload-file v-model="formData.alipay_with_crt" api="upload/cert/aliapp" />
|
<upload-file v-model="formData.alipay_with_crt" api="sys/document/aliyun" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-tip">{{ t('alipayWithCrtTips') }}</div>
|
<div class="form-tip">{{ t('alipayWithCrtTips') }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
<div class="cursor-pointer" @click="copyEvent(formData.request_url)">{{ t('copy') }}</div>
|
<div class="cursor-pointer" @click="copyEvent(formData.request_url)">{{ t('copy') }}</div>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
<span class="ml-2 cursor-pointer visit-btn" @click="visitFn">{{t('clickVisit')}}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -35,7 +36,7 @@
|
|||||||
import { reactive, ref, watch } from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { setH5Config, getH5Config } from '@/api/h5'
|
import { setH5Config, getH5Config } from '@/api/h5'
|
||||||
import { getSceneDomain } from '@/api/sys'
|
import { getUrl } from '@/api/sys'
|
||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { ElMessage, FormInstance } from 'element-plus'
|
import { ElMessage, FormInstance } from 'element-plus'
|
||||||
|
|
||||||
@ -60,8 +61,8 @@ getH5Config().then(res => {
|
|||||||
/**
|
/**
|
||||||
* 获取h5域名
|
* 获取h5域名
|
||||||
*/
|
*/
|
||||||
getSceneDomain().then(res => {
|
getUrl().then(res => {
|
||||||
formData.request_url = res.data.wap_domain
|
formData.request_url = res.data.wap_url
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -89,6 +90,11 @@ watch(copied, () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 点击访问
|
||||||
|
const visitFn = ()=>{
|
||||||
|
window.open(formData.request_url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存
|
* 保存
|
||||||
*/
|
*/
|
||||||
@ -111,4 +117,8 @@ const save = async (formEl: FormInstance | undefined) => {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.visit-btn{
|
||||||
|
color:var(--el-color-primary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,12 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container">
|
<div class="main-container" v-loading="loading">
|
||||||
<el-form label-width="120px" ref="formRef" class="page-form">
|
<el-form :model="formData" label-width="120px" ref="formRef" class="page-form">
|
||||||
|
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<h3 class="panel-title">{{ t('pcInfo') }}</h3>
|
<h3 class="panel-title">{{ t('pcInfo') }}</h3>
|
||||||
|
|
||||||
<el-form-item :label="t('preview')" prop="weapp_name">
|
<el-form-item :label="t('preview')" prop="weapp_name">
|
||||||
<img class="w-[1010px]" src="@/assets/images/channel/preview.png" alt="">
|
<img class="w-[500px]" src="@/assets/images/channel/preview.png" alt="">
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label="t('PCDomainName')">
|
||||||
|
<el-input :model-value="formData.request_url" class="input-width" :readonly="true">
|
||||||
|
<template #append>
|
||||||
|
<div class="cursor-pointer" @click="copyEvent(formData.request_url)">{{ t('copy') }}</div>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="ml-2 cursor-pointer visit-btn" @click="visitFn">{{t('clickVisit')}}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@ -15,9 +24,65 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { getUrl } from '@/api/sys'
|
||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
const formData = reactive<Record<string, string | boolean>>({
|
||||||
|
is_open: false,
|
||||||
|
request_url: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取pc域名
|
||||||
|
*/
|
||||||
|
getUrl().then(res => {
|
||||||
|
formData.request_url = res.data.web_url;
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制
|
||||||
|
*/
|
||||||
|
const { copy, isSupported, copied } = useClipboard()
|
||||||
|
const copyEvent = (text: string) => {
|
||||||
|
if (!isSupported.value) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('notSupportCopy'),
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
copy(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(copied, () => {
|
||||||
|
if (copied.value) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('copySuccess'),
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击访问
|
||||||
|
const visitFn = ()=>{
|
||||||
|
window.open(formData.request_url);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.visit-btn{
|
||||||
|
color:var(--el-color-primary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-alert class="warm-prompt" type="info">
|
<el-alert class="warm-prompt" type="info">
|
||||||
<template #default>
|
<template #default>
|
||||||
<p class="text-base">{{t('operationTip')}} 1、{{ t('operationTipOne') }}</p>
|
<p class="text-base">{{ t('operationTip') }} 1、{{ t('operationTipOne') }}</p>
|
||||||
<p class="text-base">2、{{ t('operationTipTwo') }}</p>
|
<p class="text-base">2、{{ t('operationTipTwo') }}</p>
|
||||||
</template>
|
</template>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
@ -51,7 +51,7 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getTemplateList, getBatchAcquisition } from '@/api/weapp'
|
import { getTemplateList, getBatchAcquisition } from '@/api/weapp'
|
||||||
import { updateMessageStatus } from '@/api/message'
|
import { editMessageStatus } from '@/api/notice'
|
||||||
import { ElLoading } from 'element-plus'
|
import { ElLoading } from 'element-plus'
|
||||||
|
|
||||||
const cronTableData = reactive({
|
const cronTableData = reactive({
|
||||||
@ -105,7 +105,7 @@ const infoSwitch = (res) => {
|
|||||||
data.value.key = res.key
|
data.value.key = res.key
|
||||||
data.value.type = 'weapp'
|
data.value.type = 'weapp'
|
||||||
cronTableData.loading = true
|
cronTableData.loading = true
|
||||||
updateMessageStatus(data.value).then(res => {
|
editMessageStatus(data.value).then(res => {
|
||||||
loadCronList()
|
loadCronList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
cronTableData.loading = false
|
cronTableData.loading = false
|
||||||
@ -115,13 +115,15 @@ const infoSwitch = (res) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
::v-deep .warm-prompt{
|
::v-deep .warm-prompt {
|
||||||
background-color: var(--el-color-primary-light-9);
|
background-color: var(--el-color-primary-light-9);
|
||||||
}
|
}
|
||||||
::v-deep .warm-prompt .el-icon{
|
|
||||||
|
::v-deep .warm-prompt .el-icon {
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
::v-deep .warm-prompt p{
|
|
||||||
|
::v-deep .warm-prompt p {
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -129,7 +129,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, watch } from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getWechatConfig, getWechatStatic, updateWechatConfig } from '@/api/wechat'
|
import { getWechatConfig, getWechatStatic, editWechatConfig } from '@/api/wechat'
|
||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ const save = async (formEl: FormInstance | undefined) => {
|
|||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
updateWechatConfig(formData).then(() => {
|
editWechatConfig(formData).then(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||||
import { getWechatMenu, updateWechatMenu } from '@/api/wechat'
|
import { getWechatMenu, editWechatMenu } from '@/api/wechat'
|
||||||
import menuForm from './components/menu-form.vue'
|
import menuForm from './components/menu-form.vue'
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
@ -199,7 +199,7 @@ const save = async () => {
|
|||||||
}
|
}
|
||||||
if (loading.value) return
|
if (loading.value) return
|
||||||
loading.value = true
|
loading.value = true
|
||||||
updateWechatMenu({ button: button.value }).then(() => {
|
editWechatMenu({ button: button.value }).then(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-alert class="warm-prompt" type="info">
|
<el-alert class="warm-prompt" type="info">
|
||||||
<template #default>
|
<template #default>
|
||||||
<p class="text-base">{{t('operationTip')}} 1、{{ t('operationTipOne') }}</p>
|
<p class="text-base">{{ t('operationTip') }} 1、{{ t('operationTipOne') }}</p>
|
||||||
<p class="text-base">2、{{ t('operationTipTwo') }}</p>
|
<p class="text-base">2、{{ t('operationTipTwo') }}</p>
|
||||||
<p class="text-base">3、{{ t('operationTipThree') }}</p>
|
<p class="text-base">3、{{ t('operationTipThree') }}</p>
|
||||||
<p class="text-base">4、{{ t('operationTipFour') }}</p>
|
<p class="text-base">4、{{ t('operationTipFour') }}</p>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getTemplateList, getBatchAcquisition } from '@/api/wechat'
|
import { getTemplateList, getBatchAcquisition } from '@/api/wechat'
|
||||||
import { updateMessageStatus } from '@/api/message'
|
import { editMessageStatus } from '@/api/notice'
|
||||||
import { AnyObject } from '@/types/global'
|
import { AnyObject } from '@/types/global'
|
||||||
import { ElLoading } from 'element-plus'
|
import { ElLoading } from 'element-plus'
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ const infoSwitch = (res: AnyObject) => {
|
|||||||
data.value.key = res.key
|
data.value.key = res.key
|
||||||
data.value.type = 'wechat'
|
data.value.type = 'wechat'
|
||||||
cronTableData.loading = true
|
cronTableData.loading = true
|
||||||
updateMessageStatus(data.value).then(res => {
|
editMessageStatus(data.value).then(res => {
|
||||||
loadCronList()
|
loadCronList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
cronTableData.loading = false
|
cronTableData.loading = false
|
||||||
@ -123,13 +123,15 @@ const infoSwitch = (res: AnyObject) => {
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
::v-deep .warm-prompt{
|
::v-deep .warm-prompt {
|
||||||
background-color: var(--el-color-primary-light-9);
|
background-color: var(--el-color-primary-light-9);
|
||||||
}
|
}
|
||||||
::v-deep .warm-prompt .el-icon{
|
|
||||||
|
::v-deep .warm-prompt .el-icon {
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
::v-deep .warm-prompt p{
|
|
||||||
|
::v-deep .warm-prompt p {
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="main-container flex-1">
|
<div class="main-container flex-1">
|
||||||
<el-header class="flex items-center h-[60px] bg-primary px-[20px]">
|
<el-header class="flex items-center h-[60px] bg-primary px-[20px]">
|
||||||
<div class="text-white cursor-pointer flex items-center" @click="goBack">
|
<div class="text-white cursor-pointer flex items-center" @click="goBack">
|
||||||
<el-icon size="14"><ArrowLeft /></el-icon>
|
<el-icon size="14">
|
||||||
|
<ArrowLeft />
|
||||||
|
</el-icon>
|
||||||
<span class="pl-[5px]">{{ t('back') }}</span>
|
<span class="pl-[5px]">{{ t('back') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-white ml-[10px] flex items-center">
|
<div class="text-white ml-[10px] flex items-center">
|
||||||
<span class="mr-[5px]"> | {{ t('decorating') }}:{{ diyStore.typeName }}</span>
|
<span class="mr-[5px]"> | {{ t('decorating') }}:{{ diyStore.typeName }}</span>
|
||||||
<!-- <el-icon class="font-bold"><EditPen /></el-icon>-->
|
<!-- <el-icon class="font-bold"><EditPen /></el-icon>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<el-button @click="save()">{{ t('save') }}</el-button>
|
<el-button @click="save()">{{ t('save') }}</el-button>
|
||||||
@ -21,11 +22,13 @@
|
|||||||
<!-- 组件列表区域 -->
|
<!-- 组件列表区域 -->
|
||||||
<el-scrollbar class="px-[10px]">
|
<el-scrollbar class="px-[10px]">
|
||||||
<el-collapse v-model="activeNames" @change="handleChange">
|
<el-collapse v-model="activeNames" @change="handleChange">
|
||||||
<el-collapse-item v-for="(item,index) in component" :key="index" :title="item.type_name" :name="item.type">
|
<el-collapse-item v-for="(item, key) in component" :key="key" :title="item.title" :name="key">
|
||||||
<ul class="flex flex-row flex-wrap">
|
<ul class="flex flex-row flex-wrap">
|
||||||
<li v-for="(compItem,compIndex) in item.list" :key="compIndex" class="w-2/6 text-center cursor-pointer h-[75px]" :title="compItem.title" @click="diyStore.addComponent(compItem)">
|
<li v-for="(compItem, compKey) in item.list" :key="compKey"
|
||||||
<icon :name="compItem.icon" size="23px"/>
|
class="w-2/6 text-center cursor-pointer h-[75px]" :title="compItem.title"
|
||||||
<span class="block text-base truncate">{{compItem.title}}</span>
|
@click="diyStore.addComponent(compKey, compItem)">
|
||||||
|
<icon :name="compItem.icon" size="23px" />
|
||||||
|
<span class="block text-base truncate">{{ compItem.title }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
@ -37,33 +40,42 @@
|
|||||||
<div class="preview-wrap flex-1 relative mt-[20px]">
|
<div class="preview-wrap flex-1 relative mt-[20px]">
|
||||||
|
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-button class="page-btn absolute right-[20px]" @click="diyStore.changeCurrentIndex(-99)">{{ t('pageSet')}}</el-button>
|
<el-button class="page-btn absolute right-[20px]" @click="diyStore.changeCurrentIndex(-99)">{{
|
||||||
|
t('pageSet') }}</el-button>
|
||||||
<div class="diy-view-wrap w-[375px] shadow-lg mx-auto">
|
<div class="diy-view-wrap w-[375px] shadow-lg mx-auto">
|
||||||
<div class="preview-head bg-no-repeat bg-center bg-cover" @click="diyStore.changeCurrentIndex(-99)">
|
<div class="preview-head bg-no-repeat bg-center bg-cover" @click="diyStore.changeCurrentIndex(-99)">
|
||||||
<span class="text-base block text-center truncate cursor-pointer h-[64px] leading-[84px]">{{ diyStore.global.title }}</span>
|
<span class="text-base block text-center truncate cursor-pointer h-[64px] leading-[84px]">{{
|
||||||
|
diyStore.global.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-block relative">
|
<div class="preview-block relative">
|
||||||
|
|
||||||
<ul class="quick-action absolute text-center -right-[70px] top-[20px] w-[42px] rounded shadow-md">
|
<ul
|
||||||
|
class="quick-action absolute text-center -right-[70px] top-[20px] w-[42px] rounded shadow-md">
|
||||||
<el-tooltip effect="light" :content="t('moveUpComponent')" placement="right">
|
<el-tooltip effect="light" :content="t('moveUpComponent')" placement="right">
|
||||||
<icon name="iconfont-iconjiantoushang" size="20px" class="block cursor-pointer leading-[40px]" @click="diyStore.moveUpComponent" />
|
<icon name="iconfont-iconjiantoushang" size="20px"
|
||||||
|
class="block cursor-pointer leading-[40px]" @click="diyStore.moveUpComponent" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="light" :content="t('moveDownComponent')" placement="right">
|
<el-tooltip effect="light" :content="t('moveDownComponent')" placement="right">
|
||||||
<icon name="iconfont-iconjiantouxia" size="20px" class="block cursor-pointer leading-[40px]" @click="diyStore.moveDownComponent" />
|
<icon name="iconfont-iconjiantouxia" size="20px"
|
||||||
|
class="block cursor-pointer leading-[40px]" @click="diyStore.moveDownComponent" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="light" :content="t('copyComponent')" placement="right">
|
<el-tooltip effect="light" :content="t('copyComponent')" placement="right">
|
||||||
<icon name="iconfont-iconcopy-line" size="20px" class="block cursor-pointer leading-[40px]" @click="diyStore.copyComponent" />
|
<icon name="iconfont-iconcopy-line" size="20px"
|
||||||
|
class="block cursor-pointer leading-[40px]" @click="diyStore.copyComponent" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="light" :content="t('delComponent')" placement="right">
|
<el-tooltip effect="light" :content="t('delComponent')" placement="right">
|
||||||
<icon name="iconfont-icondelete-line" size="20px" class="block cursor-pointer leading-[40px]" @click="diyStore.delComponent"/>
|
<icon name="iconfont-icondelete-line" size="20px"
|
||||||
|
class="block cursor-pointer leading-[40px]" @click="diyStore.delComponent" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="light" :content="t('resetComponent')" placement="right">
|
<el-tooltip effect="light" :content="t('resetComponent')" placement="right">
|
||||||
<icon name="iconfont-iconloader-line" size="20px" class="block cursor-pointer leading-[40px]" @click="diyStore.resetComponent" />
|
<icon name="iconfont-iconloader-line" size="20px"
|
||||||
|
class="block cursor-pointer leading-[40px]" @click="diyStore.resetComponent" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- 组件预览渲染区域 -->
|
<!-- 组件预览渲染区域 -->
|
||||||
<iframe id="previewIframe" v-show="wapDomain" :src="wapDomain" frameborder="0" class="preview-iframe w-[375px]"></iframe>
|
<iframe id="previewIframe" v-show="wapDomain" :src="wapDomain" frameborder="0"
|
||||||
|
class="preview-iframe w-[375px]"></iframe>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -78,10 +90,12 @@
|
|||||||
<el-card class="box-card" shadow="never">
|
<el-card class="box-card" shadow="never">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header flex justify-between items-center">
|
<div class="card-header flex justify-between items-center">
|
||||||
<span class="title flex-1">{{ diyStore.currentIndex == -99 ? t('pageSet') : diyStore.editComponent.componentTitle }}</span>
|
<span class="title flex-1">{{ diyStore.currentIndex == -99 ? t('pageSet') :
|
||||||
|
diyStore.editComponent.componentTitle }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<component :is="modules[diyStore.currentComponent]" :value="diyStore.value[diyStore.currentIndex]" />
|
<component :is="modules[diyStore.currentComponent]"
|
||||||
|
:value="diyStore.value[diyStore.currentIndex]" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
|
||||||
@ -92,34 +106,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, reactive, toRaw, onMounted, watch} from 'vue'
|
import { ref, reactive, toRaw, onMounted, watch } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { addDiyPage, updateDiyPage,initPage} from '@/api/diy';
|
import { addDiyPage, editDiyPage, initPage } from '@/api/diy';
|
||||||
import {useRoute,useRouter} from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { cloneDeep, range, isEmpty } from 'lodash-es'
|
import { cloneDeep, range, isEmpty } from 'lodash-es'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import { getWapDomain } from '@/utils/common'
|
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const wapDomain = ref('')
|
const wapDomain = ref('')
|
||||||
|
|
||||||
const component = ref([])
|
const component = ref([])
|
||||||
const componentType:string[] = reactive([])
|
const componentType: string[] = reactive([])
|
||||||
|
|
||||||
const activeNames = ref(componentType)
|
const activeNames = ref(componentType)
|
||||||
const handleChange = (val: string[]) => {}
|
const handleChange = (val: string[]) => { }
|
||||||
|
|
||||||
route.query.id = route.query.id || 0;
|
route.query.id = route.query.id || 0;
|
||||||
route.query.name = route.query.name || '';
|
route.query.name = route.query.name || '';
|
||||||
route.query.type = route.query.type || ''; // 页面类型,新页面传入
|
route.query.type = route.query.type || ''; // 页面类型,新页面传入
|
||||||
route.query.title = route.query.title || '';
|
route.query.title = route.query.title || '';
|
||||||
|
|
||||||
// 初始化原数据
|
// 初始化原数据
|
||||||
const originData = reactive({
|
const originData = reactive({
|
||||||
id: diyStore.id,
|
id: diyStore.id,
|
||||||
name: diyStore.name,
|
name: diyStore.name,
|
||||||
title: diyStore.global.title,
|
title: diyStore.global.title,
|
||||||
@ -127,14 +140,14 @@
|
|||||||
global: toRaw(diyStore.global),
|
global: toRaw(diyStore.global),
|
||||||
value: toRaw(diyStore.value)
|
value: toRaw(diyStore.value)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 返回上一页
|
// 返回上一页
|
||||||
const isChange = ref(true) // 数据是否发生变化,true:没变化,false:变化了
|
const isChange = ref(true) // 数据是否发生变化,true:没变化,false:变化了
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
if(isChange.value){
|
if (isChange.value) {
|
||||||
router.push('/diy/list');
|
router.push('/diy/list');
|
||||||
}else{
|
} else {
|
||||||
// 数据发生变化,弹框提示:确定离开此页面
|
// 数据发生变化,弹框提示:确定离开此页面
|
||||||
ElMessageBox.confirm(
|
ElMessageBox.confirm(
|
||||||
t('leavePageTitleTips'),
|
t('leavePageTitleTips'),
|
||||||
@ -150,19 +163,19 @@
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态加载后台自定义组件编辑
|
// 动态加载后台自定义组件编辑
|
||||||
const modulesFiles = import.meta.glob('./components/*.vue', {eager: true})
|
const modulesFiles = import.meta.glob('./components/*.vue', { eager: true })
|
||||||
const modules = {}
|
const modules = {}
|
||||||
for (const [key, value] of Object.entries(modulesFiles)) {
|
for (const [key, value] of Object.entries(modulesFiles)) {
|
||||||
const moduleName = key.replace(/^\.\/(.*)\.\w+$/, '$1')
|
const moduleName = key.replace(/^\.\/(.*)\.\w+$/, '$1')
|
||||||
const name = moduleName.split('/')[1]
|
const name = moduleName.split('/')[1]
|
||||||
modules[name] = value.default
|
modules[name] = value.default
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全局监听自定义数据变化
|
// 全局监听自定义数据变化
|
||||||
watch(
|
watch(
|
||||||
() => diyStore,
|
() => diyStore,
|
||||||
(newValue, oldValue) => {
|
(newValue, oldValue) => {
|
||||||
let data = {
|
let data = {
|
||||||
@ -179,16 +192,15 @@
|
|||||||
isChange.value = JSON.stringify(data) == JSON.stringify(originData);
|
isChange.value = JSON.stringify(data) == JSON.stringify(originData);
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 根据当前页面路由查询页面初始化数据
|
// 根据当前页面路由查询页面初始化数据
|
||||||
initPage({
|
initPage({
|
||||||
id:route.query.id,
|
id: route.query.id,
|
||||||
name:route.query.name,
|
name: route.query.name,
|
||||||
type:route.query.type,
|
type: route.query.type,
|
||||||
title:route.query.title
|
title: route.query.title
|
||||||
}).then(res=> {
|
}).then(res => {
|
||||||
if (res.code == 200) {
|
|
||||||
let data = res.data;
|
let data = res.data;
|
||||||
diyStore.id = data.id || 0;
|
diyStore.id = data.id || 0;
|
||||||
diyStore.name = data.name;
|
diyStore.name = data.name;
|
||||||
@ -197,7 +209,7 @@
|
|||||||
if (data.value) {
|
if (data.value) {
|
||||||
let sources = JSON.parse(data.value);
|
let sources = JSON.parse(data.value);
|
||||||
diyStore.global = sources.global;
|
diyStore.global = sources.global;
|
||||||
if(sources.value.length) {
|
if (sources.value.length) {
|
||||||
diyStore.value = sources.value;
|
diyStore.value = sources.value;
|
||||||
// diyStore.changeCurrentIndex(0,diyStore.value[0]);
|
// diyStore.changeCurrentIndex(0,diyStore.value[0]);
|
||||||
}
|
}
|
||||||
@ -215,12 +227,12 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
component.value = data.component
|
component.value = data.component
|
||||||
component.value.forEach((item: any) => {
|
for (let type in component.value) {
|
||||||
componentType.push(item.type)
|
componentType.push(type)
|
||||||
item.list.forEach((comp: any) => {
|
for (let key in component.value[type].list) {
|
||||||
let com = cloneDeep(comp);
|
let com = cloneDeep(component.value[type].list[key]);
|
||||||
com.id = diyStore.generateRandom();
|
com.id = diyStore.generateRandom();
|
||||||
com.componentName = com.name;
|
com.componentName = key;
|
||||||
com.componentTitle = com.title;
|
com.componentTitle = com.title;
|
||||||
com.maxCount = com.max_count;
|
com.maxCount = com.max_count;
|
||||||
Object.assign(com, com.value);
|
Object.assign(com, com.value);
|
||||||
@ -231,20 +243,19 @@
|
|||||||
delete com.icon;
|
delete com.icon;
|
||||||
delete com.max_count;
|
delete com.max_count;
|
||||||
diyStore.components.push(com)
|
diyStore.components.push(com)
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
wapDomain.value = `${getWapDomain()}/${data.page}?mode=decorate`; // 模式:decorate 装修 访问预览页面
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
wapDomain.value = `${data.domain_url.wap_url}/${data.page}?mode=decorate`; // 模式:decorate 装修 访问预览页面
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
// 预览前端 uniapp iframe
|
// 预览前端 uniapp iframe
|
||||||
window.previewIframe = document.getElementById('previewIframe')
|
window.previewIframe = document.getElementById('previewIframe')
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听组件数据 uni-app端
|
// 监听组件数据 uni-app端
|
||||||
window.addEventListener('message', (event) => {
|
window.addEventListener('message', (event) => {
|
||||||
try {
|
try {
|
||||||
let data = JSON.parse(event.data);
|
let data = JSON.parse(event.data);
|
||||||
if (!data.type) return;
|
if (!data.type) return;
|
||||||
@ -267,12 +278,12 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('后台接受数据错误',e)
|
console.log('后台接受数据错误', e)
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const save = ()=> {
|
const save = () => {
|
||||||
if (!diyStore.verify()) {
|
if (!diyStore.verify()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -291,7 +302,7 @@
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = diyStore.id ? updateDiyPage : addDiyPage
|
const save = diyStore.id ? editDiyPage : addDiyPage
|
||||||
save(data).then((res: any) => {
|
save(data).then((res: any) => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
@ -305,61 +316,59 @@
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.el-collapse-item__wrap {
|
.el-collapse-item__wrap {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__content {
|
.el-collapse-item__content {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-collapse-item__header {
|
.el-collapse-item__header {
|
||||||
font-size: var(--el-font-size-base);
|
font-size: var(--el-font-size-base);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.full-container {
|
.full-container {
|
||||||
height: calc(100vh - 60px);
|
height: calc(100vh - 60px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-iframe{
|
.preview-iframe {
|
||||||
height: calc(100vh - 160px);
|
height: calc(100vh - 160px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-list {
|
.component-list {
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-list ul li {
|
.component-list ul li {
|
||||||
&:not(.disabled):hover {
|
&:not(.disabled):hover {
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
background: var(--el-color-primary-light-9);
|
background: var(--el-color-primary-light-9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.diy-view-wrap {
|
.diy-view-wrap {
|
||||||
background: var(--el-bg-color-page);
|
background: var(--el-bg-color-page);
|
||||||
}
|
}
|
||||||
|
|
||||||
.diy-view-wrap .preview-head {
|
.diy-view-wrap .preview-head {
|
||||||
background-image: url(assets/images/diy_preview_head.png);
|
background-image: url(assets/images/diy_preview_head.png);
|
||||||
background-color: var(--el-bg-color);
|
background-color: var(--el-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.quick-action {
|
.quick-action {
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-attribute-wrap {
|
.edit-attribute-wrap {
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-attribute-wrap .box-card {
|
.edit-attribute-wrap .box-card {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}</style>
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -49,18 +49,21 @@
|
|||||||
import {t} from '@/lang'
|
import {t} from '@/lang'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
import {getWeappConfig} from '@/api/weapp'
|
import {getWeappConfig} from '@/api/weapp'
|
||||||
|
import {getUrl} from '@/api/sys'
|
||||||
import {useClipboard} from '@vueuse/core'
|
import {useClipboard} from '@vueuse/core'
|
||||||
import {ElMessage} from 'element-plus'
|
import {ElMessage} from 'element-plus'
|
||||||
import {img} from '@/utils/common'
|
import {img} from '@/utils/common'
|
||||||
import {getWapDomain} from '@/utils/common'
|
|
||||||
import QRCode from "qrcode";
|
import QRCode from "qrcode";
|
||||||
|
|
||||||
const wapDomain = ref(getWapDomain() + '/pages/index/index')
|
const wapDomain = ref('')
|
||||||
const wapImage = ref('')
|
const wapImage = ref('')
|
||||||
|
|
||||||
|
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 => {
|
QRCode.toDataURL(wapDomain.value, {errorCorrectionLevel: 'L', margin: 0, width: 100}).then(url => {
|
||||||
wapImage.value = url
|
wapImage.value = url
|
||||||
})
|
})
|
||||||
|
});
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -84,6 +87,7 @@
|
|||||||
path: '/decorate/edit',
|
path: '/decorate/edit',
|
||||||
query: {name: 'DIY_INDEX'}
|
query: {name: 'DIY_INDEX'}
|
||||||
});
|
});
|
||||||
|
|
||||||
const toDecorate = () => {
|
const toDecorate = () => {
|
||||||
router.push('/decorate/edit?name=DIY_INDEX')
|
router.push('/decorate/edit?name=DIY_INDEX')
|
||||||
// window.open(url.href);
|
// window.open(url.href);
|
||||||
|
|||||||
@ -2,29 +2,21 @@
|
|||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-button type="primary" @click="dialogVisible=true">
|
<el-button type="primary" @click="dialogVisible = true">
|
||||||
{{ t('addDiyPage') }}
|
{{ t('addDiyPage') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card class="box-card !border-none my-[16px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none my-[16px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="diyRouteTableData.searchParam" ref="searchFormDiyRouteRef" v-if="tabValue == 'route'">
|
<el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef"
|
||||||
|
v-if="tabValue == 'diy'">
|
||||||
<el-form-item :label="t('title')" prop="title">
|
<el-form-item :label="t('title')" prop="title">
|
||||||
<el-input v-model="diyRouteTableData.searchParam.title" :placeholder="t('titlePlaceholder')"/>
|
<el-input v-model="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" @click="loadDiyRouteList()">{{ t('search') }}</el-button>
|
|
||||||
<el-button @click="searchFormDiyRouteRef?.resetFields()">{{ t('reset') }}</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef" v-if="tabValue == 'diy'">
|
|
||||||
<el-form-item :label="t('title')" prop="title">
|
|
||||||
<el-input v-model="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')"/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('typeName')" prop="type">
|
<el-form-item :label="t('typeName')" prop="type">
|
||||||
<el-select v-model="diyPageTableData.searchParam.type" :placeholder="t('pageTypePlaceholder')">
|
<el-select v-model="diyPageTableData.searchParam.type" :placeholder="t('pageTypePlaceholder')">
|
||||||
<el-option :label="t('all')" value="" />
|
<el-option :label="t('all')" value="" />
|
||||||
<el-option v-for="item in pageType" :label="item.type_name" :value="item.type" />
|
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@ -32,6 +24,16 @@
|
|||||||
<el-button @click="searchFormDiyPageRef?.resetFields()">{{ t('reset') }}</el-button>
|
<el-button @click="searchFormDiyPageRef?.resetFields()">{{ t('reset') }}</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<el-form :inline="true" :model="diyRouteTableData.searchParam" ref="searchFormDiyRouteRef"
|
||||||
|
v-if="tabValue == 'route'">
|
||||||
|
<el-form-item :label="t('title')" prop="title">
|
||||||
|
<el-input v-model="diyRouteTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="loadDiyRouteList()">{{ t('search') }}</el-button>
|
||||||
|
<el-button @click="searchFormDiyRouteRef?.resetFields()">{{ t('reset') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<div class="mt-[16px]">
|
<div class="mt-[16px]">
|
||||||
@ -45,9 +47,9 @@
|
|||||||
<span>{{ !diyPageTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !diyPageTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table-column prop="title" :label="t('title')" min-width="120"/>
|
<el-table-column prop="title" :label="t('title')" min-width="120" />
|
||||||
<el-table-column prop="type_name" :label="t('typeName')" min-width="80"/>
|
<el-table-column prop="type_name" :label="t('typeName')" min-width="80" />
|
||||||
<el-table-column :label="t('status')" min-width="120">
|
<el-table-column :label="t('status')" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row.type == 'DIY_PAGE'">-</span>
|
<span v-if="row.type == 'DIY_PAGE'">-</span>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@ -56,21 +58,27 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="update_time" :label="t('updateTime')" min-width="120"/>
|
<el-table-column prop="update_time" :label="t('updateTime')" min-width="120" />
|
||||||
|
|
||||||
<el-table-column :label="t('operation')" fixed="right" min-width="120">
|
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="160">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="promoteEvent(row)">{{ t('promote') }}</el-button>
|
<el-button type="primary" link @click="promoteEvent(row)">{{ t('promote') }}</el-button>
|
||||||
<el-button v-if="row.type != 'DIY_PAGE' && row.is_default == 0" type="primary" link @click="setUse(row)">{{ t('use') }}</el-button>
|
<el-button v-if="row.type != 'DIY_PAGE' && row.is_default == 0" type="primary" link
|
||||||
<el-button v-if="row.type == 'DIY_PAGE'" type="primary" link @click="openShare(row)">{{ t('shareSet') }}</el-button>
|
@click="setUse(row)">{{ t('use') }}</el-button>
|
||||||
|
<el-button v-if="row.type == 'DIY_PAGE'" type="primary" link @click="openShare(row)">{{
|
||||||
|
t('shareSet') }}</el-button>
|
||||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||||
<el-button v-if="row.type == 'DIY_PAGE' || row.is_default == 0" type="danger" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
|
<el-button v-if="row.type == 'DIY_PAGE' || row.is_default == 0" type="danger" link
|
||||||
|
@click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="mt-[16px] flex justify-end">
|
<div class="mt-[16px] flex justify-end">
|
||||||
<el-pagination v-model:current-page="diyPageTableData.page" v-model:page-size="diyPageTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="diyPageTableData.total" @size-change="loadDiyPageList()" @current-change="loadDiyPageList"/>
|
<el-pagination v-model:current-page="diyPageTableData.page"
|
||||||
|
v-model:page-size="diyPageTableData.limit" layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="diyPageTableData.total" @size-change="loadDiyPageList()"
|
||||||
|
@current-change="loadDiyPageList" />
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- 基础页面路径 -->
|
<!-- 基础页面路径 -->
|
||||||
@ -79,11 +87,12 @@
|
|||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !diyRouteTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !diyRouteTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column prop="title" :label="t('title')" min-width="120"/>
|
<el-table-column prop="title" :label="t('title')" min-width="120" />
|
||||||
<el-table-column prop="page" :label="t('wapUrl')" min-width="120">
|
<el-table-column prop="page" :label="t('wapUrl')" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span class="mr-[10px]">{{ getWapDomain() + row.page }}</span>
|
<span class="mr-[10px]">{{ wapDomain + row.page }}</span>
|
||||||
<el-button type="primary" link @click="copyEvent(getWapDomain() + row.page)">{{ t('copy') }}</el-button>
|
<el-button type="primary" link @click="copyEvent(wapDomain + row.page)">{{ t('copy')
|
||||||
|
}}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="page" :label="t('weappUrl')" min-width="120">
|
<el-table-column prop="page" :label="t('weappUrl')" min-width="120">
|
||||||
@ -94,13 +103,11 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('share')" fixed="right" min-width="80">
|
<el-table-column :label="t('share')" fixed="right" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button v-if="row.is_share == 1" type="primary" link @click="openShare(row)">{{ t('shareSet') }}</el-button>
|
<el-button v-if="row.is_share == 1" type="primary" link @click="openShare(row)">{{
|
||||||
|
t('shareSet') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="mt-[16px] flex justify-end">
|
|
||||||
<el-pagination v-model:current-page="diyRouteTableData.page" v-model:page-size="diyRouteTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="diyRouteTableData.total" @size-change="loadDiyPageList()" @current-change="loadDiyPageList"/>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
@ -115,17 +122,18 @@
|
|||||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules">
|
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules">
|
||||||
<el-form-item :label="t('typeName')" prop="type">
|
<el-form-item :label="t('typeName')" prop="type">
|
||||||
<el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')">
|
<el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')">
|
||||||
<el-option v-for="item in pageType" :label="item.type_name" :value="item.type" />
|
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('title')" prop="title">
|
<el-form-item :label="t('title')" prop="title">
|
||||||
<el-input v-model="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12" show-word-limit/>
|
<el-input v-model="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12"
|
||||||
|
show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="dialogVisible = false">{{ t('cancel')}}</el-button>
|
<el-button @click="dialogVisible = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="addEvent(formRef)">{{ t('confirm') }}</el-button>
|
<el-button type="primary" @click="addEvent(formRef)">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@ -143,19 +151,21 @@
|
|||||||
<span>{{ sharePage }}</span>
|
<span>{{ sharePage }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('shareTitle')" prop="title">
|
<el-form-item :label="t('shareTitle')" prop="title">
|
||||||
<el-input v-model="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')" clearable maxlength="30" show-word-limit/>
|
<el-input v-model="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')"
|
||||||
|
clearable maxlength="30" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'">
|
<el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'">
|
||||||
<el-input v-model="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')" type="textarea" rows="4" clearable maxlength="100" show-word-limit/>
|
<el-input v-model="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')"
|
||||||
|
type="textarea" rows="4" clearable maxlength="100" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('shareImageUrl')" prop="url">
|
<el-form-item :label="t('shareImageUrl')" prop="url">
|
||||||
<upload-image v-model="shareFormData[tabShareType].url" :limit="1"/>
|
<upload-image v-model="shareFormData[tabShareType].url" :limit="1" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="shareDialogVisible = false">{{ t('cancel')}}</el-button>
|
<el-button @click="shareDialogVisible = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="shareEvent(shareFormRef)">{{ t('confirm') }}</el-button>
|
<el-button type="primary" @click="shareEvent(shareFormRef)">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@ -165,21 +175,22 @@
|
|||||||
<el-dialog v-model="promoteDialogVisible" :title="t('promote')" width="30%">
|
<el-dialog v-model="promoteDialogVisible" :title="t('promote')" width="30%">
|
||||||
<el-form label-width="90px">
|
<el-form label-width="90px">
|
||||||
<el-form-item :label="t('shareLink')">
|
<el-form-item :label="t('shareLink')">
|
||||||
<el-input readonly :value="wapDomain">
|
<el-input readonly :value="promoteWapDomain">
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button @click="copyEvent(wapDomain)" class="bg-primary copy">{{ t('copy') }}</el-button>
|
<el-button @click="copyEvent(promoteWapDomain)" class="bg-primary copy">{{ t('copy')
|
||||||
|
}}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label=" ">
|
<el-form-item label=" ">
|
||||||
<el-image :src="wapImage"/>
|
<el-image :src="wapImage" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- <el-tabs v-model="tabPromote">-->
|
<!-- <el-tabs v-model="tabPromote">-->
|
||||||
<!-- <el-tab-pane :label="t('wechat')" name="wechat"></el-tab-pane>-->
|
<!-- <el-tab-pane :label="t('wechat')" name="wechat"></el-tab-pane>-->
|
||||||
<!-- <el-tab-pane :label="t('weapp')" name="weapp"></el-tab-pane>-->
|
<!-- <el-tab-pane :label="t('weapp')" name="weapp"></el-tab-pane>-->
|
||||||
<!-- </el-tabs>-->
|
<!-- </el-tabs>-->
|
||||||
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
@ -187,26 +198,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {reactive, ref,watch,computed} from 'vue'
|
import { reactive, ref, watch, computed } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import {getDiyPageList, deleteDiyPage, setUseDiyPage,getDiyPageType,getDiyRouteList,updateDiyPageShare,updateDiyRouteShare} from '@/api/diy'
|
import { getDiyPageList, deleteDiyPage, setUseDiyPage, getDiyPageType, getDiyRouteList, getDiyRouteInfo, editDiyPageShare, editDiyRouteShare } from '@/api/diy'
|
||||||
import {TabsPaneContext, ElMessage,ElMessageBox,FormInstance} from 'element-plus'
|
import { TabsPaneContext, ElMessage, ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import {useRouter} from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import {useClipboard} from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { getWapDomain } from '@/utils/common'
|
import QRCode from "qrcode";
|
||||||
import QRCode from "qrcode";
|
import { getUrl } from '@/api/sys'
|
||||||
|
|
||||||
const pageType:any = reactive([])
|
const pageType: any = reactive({})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
// 添加自定义页面
|
// 添加自定义页面
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
title: ''
|
title: ''
|
||||||
})
|
})
|
||||||
// 表单验证规则
|
|
||||||
const formRules = computed(() => {
|
// 表单验证规则
|
||||||
|
const formRules = computed(() => {
|
||||||
return {
|
return {
|
||||||
type: [
|
type: [
|
||||||
{ required: true, message: t('pageTypePlaceholder'), trigger: 'blur' },
|
{ required: true, message: t('pageTypePlaceholder'), trigger: 'blur' },
|
||||||
@ -215,10 +227,11 @@
|
|||||||
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' },
|
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
const dialogVisible = ref(false)
|
const formRef = ref<FormInstance>()
|
||||||
const addEvent = async (formEl: FormInstance | undefined) => {
|
const dialogVisible = ref(false)
|
||||||
|
const addEvent = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
@ -227,48 +240,47 @@
|
|||||||
router.push('/decorate/edit?type=' + formData.type + '&title=' + formData.title);
|
router.push('/decorate/edit?type=' + formData.type + '&title=' + formData.title);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let diyRouteTableData = reactive({
|
let diyRouteTableData = reactive({
|
||||||
page: 1,
|
|
||||||
limit: 10,
|
|
||||||
total: 0,
|
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
"title":"",
|
"title": "",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
const wapDomain = ref('')
|
||||||
|
const getDomain = async () => {
|
||||||
|
wapDomain.value = (await getUrl()).data.wap_url;
|
||||||
|
};
|
||||||
|
getDomain();
|
||||||
|
|
||||||
|
/**
|
||||||
* 获取自定义路由列表
|
* 获取自定义路由列表
|
||||||
*/
|
*/
|
||||||
const loadDiyRouteList = (page: number = 1) => {
|
const loadDiyRouteList = () => {
|
||||||
diyRouteTableData.loading = true
|
diyRouteTableData.loading = true
|
||||||
diyRouteTableData.page = page
|
|
||||||
|
|
||||||
getDiyRouteList({
|
getDiyRouteList({
|
||||||
page: diyRouteTableData.page,
|
|
||||||
limit: diyRouteTableData.limit,
|
|
||||||
...diyRouteTableData.searchParam
|
...diyRouteTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
diyRouteTableData.loading = false
|
diyRouteTableData.loading = false
|
||||||
diyRouteTableData.data = res.data.data
|
diyRouteTableData.data = res.data
|
||||||
diyRouteTableData.total = res.data.total
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
diyRouteTableData.loading = false
|
diyRouteTableData.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
loadDiyRouteList()
|
loadDiyRouteList()
|
||||||
|
|
||||||
// 获取自定义页面类型
|
// 获取自定义页面类型
|
||||||
getDiyPageType({}).then(res=>{
|
getDiyPageType({}).then(res => {
|
||||||
for (let item in res.data){
|
for (let key in res.data) {
|
||||||
pageType.push(res.data[item])
|
pageType[key] = res.data[key]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let diyPageTableData:any = reactive({
|
let diyPageTableData: any = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
@ -278,25 +290,24 @@
|
|||||||
"title": "",
|
"title": "",
|
||||||
"type": '',
|
"type": '',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabValue = ref('diy')
|
const tabValue = ref('diy')
|
||||||
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
||||||
tabValue.value = tab.props.name;
|
tabValue.value = tab.props.name;
|
||||||
if(tabValue.value == 'diy'){
|
if (tabValue.value == 'diy') {
|
||||||
loadDiyPageList()
|
loadDiyPageList()
|
||||||
}else{
|
} else {
|
||||||
loadDiyRouteList()
|
loadDiyRouteList()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchFormDiyRouteRef = ref<FormInstance>()
|
const searchFormDiyRouteRef = ref<FormInstance>()
|
||||||
|
const searchFormDiyPageRef = ref<FormInstance>()
|
||||||
|
|
||||||
const searchFormDiyPageRef = ref<FormInstance>()
|
// 获取自定义页面列表
|
||||||
|
const loadDiyPageList = (page: number = 1) => {
|
||||||
// 获取自定义页面列表
|
|
||||||
const loadDiyPageList = (page: number = 1) => {
|
|
||||||
diyPageTableData.loading = true
|
diyPageTableData.loading = true
|
||||||
diyPageTableData.page = page
|
diyPageTableData.page = page
|
||||||
|
|
||||||
@ -311,21 +322,21 @@
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
diyPageTableData.loading = false
|
diyPageTableData.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDiyPageList()
|
loadDiyPageList()
|
||||||
|
|
||||||
// 编辑自定义页面
|
// 编辑自定义页面
|
||||||
const editEvent = (data: any) => {
|
const editEvent = (data: any) => {
|
||||||
let url = router.resolve({
|
let url = router.resolve({
|
||||||
path: '/decorate/edit',
|
path: '/decorate/edit',
|
||||||
query: {id: data.id}
|
query: { id: data.id }
|
||||||
});
|
});
|
||||||
window.open(url.href);
|
window.open(url.href);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除自定义页面
|
// 删除自定义页面
|
||||||
const deleteEvent = (id: number) => {
|
const deleteEvent = (id: number) => {
|
||||||
ElMessageBox.confirm(t('diyPageDeleteTips'), t('warning'),
|
ElMessageBox.confirm(t('diyPageDeleteTips'), t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@ -338,20 +349,20 @@
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设为使用
|
// 设为使用
|
||||||
const setUse = (data: any) => {
|
const setUse = (data: any) => {
|
||||||
setUseDiyPage({id: data.id}).then(() => {
|
setUseDiyPage({ id: data.id }).then(() => {
|
||||||
loadDiyPageList()
|
loadDiyPageList()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制
|
* 复制
|
||||||
*/
|
*/
|
||||||
const {copy, isSupported, copied} = useClipboard()
|
const { copy, isSupported, copied } = useClipboard()
|
||||||
const copyEvent = (text: string) => {
|
const copyEvent = (text: string) => {
|
||||||
if (!isSupported.value) {
|
if (!isSupported.value) {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: t('notSupportCopy'),
|
message: t('notSupportCopy'),
|
||||||
@ -359,33 +370,40 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
copy(text)
|
copy(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(copied, () => {
|
watch(copied, () => {
|
||||||
if (copied.value) {
|
if (copied.value) {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: t('copySuccess'),
|
message: t('copySuccess'),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabShareType = ref('wechat')
|
const tabShareType = ref('wechat')
|
||||||
const sharePage = ref('')
|
const sharePage = ref('')
|
||||||
const shareFormId = ref(0)
|
const shareFormId = ref(0)
|
||||||
const shareFormData = reactive({
|
const diyRouteData = reactive({
|
||||||
wechat:{
|
title: '',
|
||||||
|
name: '',
|
||||||
|
page: '',
|
||||||
|
is_share: 0,
|
||||||
|
sort: 0
|
||||||
|
})
|
||||||
|
const shareFormData = reactive({
|
||||||
|
wechat: {
|
||||||
title: '',
|
title: '',
|
||||||
desc: '',
|
desc: '',
|
||||||
url: ''
|
url: ''
|
||||||
},
|
},
|
||||||
weapp:{
|
weapp: {
|
||||||
title: '',
|
title: '',
|
||||||
url: ''
|
url: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const shareDialogVisible = ref(false)
|
const shareDialogVisible = ref(false)
|
||||||
const shareFormRules = computed(() => {
|
const shareFormRules = computed(() => {
|
||||||
return {
|
return {
|
||||||
// title: [
|
// title: [
|
||||||
// { required: true, message: t('shareTitlePlaceholder'), trigger: 'blur' },
|
// { required: true, message: t('shareTitlePlaceholder'), trigger: 'blur' },
|
||||||
@ -401,15 +419,38 @@
|
|||||||
// // }
|
// // }
|
||||||
// ],
|
// ],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const shareFormRef = ref<FormInstance>()
|
const shareFormRef = ref<FormInstance>()
|
||||||
const openShare = (row:any)=> {
|
const openShare = async (row: any) => {
|
||||||
|
if (tabValue.value == 'route') {
|
||||||
|
// 基础页面
|
||||||
|
let info = (await getDiyRouteInfo({
|
||||||
|
name: row.name
|
||||||
|
})).data;
|
||||||
|
|
||||||
|
if (info.title) {
|
||||||
|
row.id = info.id;
|
||||||
|
row.title = info.title
|
||||||
|
row.name = info.name
|
||||||
|
row.page = info.page
|
||||||
|
row.is_share = info.is_share
|
||||||
|
row.sort = info.sort
|
||||||
|
row.share = info.share
|
||||||
|
}
|
||||||
|
|
||||||
|
diyRouteData.title = row.title
|
||||||
|
diyRouteData.name = row.name
|
||||||
|
diyRouteData.page = row.page
|
||||||
|
diyRouteData.is_share = row.is_share
|
||||||
|
diyRouteData.sort = row.sort
|
||||||
|
|
||||||
|
}
|
||||||
shareFormId.value = row.id;
|
shareFormId.value = row.id;
|
||||||
sharePage.value = row.title;
|
sharePage.value = row.title;
|
||||||
let share = row.share ? JSON.parse(row.share) : {
|
let share = row.share ? JSON.parse(row.share) : {
|
||||||
wechat: {title: '', desc: '', url: ''},
|
wechat: { title: '', desc: '', url: '' },
|
||||||
weapp: {title: '', url: ''}
|
weapp: { title: '', url: '' }
|
||||||
};
|
};
|
||||||
if (share) {
|
if (share) {
|
||||||
shareFormData.wechat = share.wechat;
|
shareFormData.wechat = share.wechat;
|
||||||
@ -417,21 +458,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
shareDialogVisible.value = true;
|
shareDialogVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const shareEvent = async (formEl: FormInstance | undefined) => {
|
const shareEvent = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let save = tabValue.value == 'diy' ? updateDiyPageShare : updateDiyRouteShare
|
let save = tabValue.value == 'diy' ? editDiyPageShare : editDiyRouteShare
|
||||||
save({
|
save({
|
||||||
id:shareFormId.value,
|
id: shareFormId.value,
|
||||||
share:JSON.stringify(shareFormData)
|
share: JSON.stringify(shareFormData),
|
||||||
|
...diyRouteData
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if(tabValue.value == 'diy'){
|
if (tabValue.value == 'diy') {
|
||||||
loadDiyPageList()
|
loadDiyPageList()
|
||||||
}else{
|
} else {
|
||||||
loadDiyRouteList()
|
loadDiyRouteList()
|
||||||
}
|
}
|
||||||
shareDialogVisible.value = false;
|
shareDialogVisible.value = false;
|
||||||
@ -439,27 +481,27 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const promoteDialogVisible = ref(false)
|
const promoteDialogVisible = ref(false)
|
||||||
const tabPromote = ref('wechat')
|
const tabPromote = ref('wechat')
|
||||||
const wapDomain = ref('')
|
const promoteWapDomain = ref('')
|
||||||
const wapImage = ref('')
|
const wapImage = ref('')
|
||||||
const promoteEvent = (data:any)=>{
|
const promoteEvent = (data: any) => {
|
||||||
wapDomain.value = getWapDomain() + '/pages/index/diy?id=' + data.id;
|
promoteWapDomain.value = wapDomain.value + '/pages/index/diy?id=' + data.id;
|
||||||
QRCode.toDataURL(wapDomain.value, {errorCorrectionLevel: 'L', margin: 0, width: 100}).then(url => {
|
QRCode.toDataURL(promoteWapDomain.value, { errorCorrectionLevel: 'L', margin: 0, width: 100 }).then(url => {
|
||||||
wapImage.value = url
|
wapImage.value = url
|
||||||
})
|
})
|
||||||
|
|
||||||
promoteDialogVisible.value = true;
|
promoteDialogVisible.value = true;
|
||||||
console.log('promoteEvent',data)
|
console.log('promoteEvent', data)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.copy {
|
.copy {
|
||||||
background: var(--el-color-primary) !important;
|
background: var(--el-color-primary) !important;
|
||||||
color: var(--el-color-white) !important;
|
color: var(--el-color-white) !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
@ -5,9 +5,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
import {useRouter} from 'vue-router'
|
import {useRouter} from 'vue-router'
|
||||||
import {getWapDomain} from '@/utils/common'
|
|
||||||
|
|
||||||
const wapDomain = ref(getWapDomain() + '/pages/member/index')
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const url = router.resolve({
|
const url = router.resolve({
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="error404">
|
|
||||||
<error code="403" :title="t('tips')" :show-btn="false">
|
|
||||||
<template #content>
|
|
||||||
<div class="flex justify-center">
|
|
||||||
<img class="w-[150px] h-[150px]" src="@/assets/images/no_perms.png" alt="" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</error>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import error from './components/error.vue'
|
|
||||||
import { t } from '@/lang'
|
|
||||||
</script>
|
|
||||||
@ -1,9 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="error404">
|
<div class="error">
|
||||||
<error code="404" title="哎呀,出错了!您访问的页面不存在…"></error>
|
<div>
|
||||||
|
<slot name="content">
|
||||||
|
<div class="error-code">404</div>
|
||||||
|
</slot>
|
||||||
|
<div class="text-lg text-tx-secondary mt-7 mb-7">页面不存在</div>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" @click="router.go(-1)">
|
||||||
|
{{ second }} 秒后返回上一页
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Error from './components/error.vue'
|
import { onUnmounted, ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
let timer: any = null
|
||||||
|
const second = ref(5)
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
timer = setInterval(() => {
|
||||||
|
if (second.value === 0) {
|
||||||
|
clearInterval(timer)
|
||||||
|
router.go(-1)
|
||||||
|
} else {
|
||||||
|
second.value--
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
timer && clearInterval(timer)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.error {
|
||||||
|
text-align: center;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.error-code {
|
||||||
|
@apply text-primary;
|
||||||
|
font-size: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 176px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="error">
|
|
||||||
<div>
|
|
||||||
<slot name="content">
|
|
||||||
<div class="error-code">{{ code }}</div>
|
|
||||||
</slot>
|
|
||||||
<div class="text-lg text-tx-secondary mt-7 mb-7">{{ title }}</div>
|
|
||||||
<el-button v-if="showBtn" type="primary" @click="router.go(-1)">
|
|
||||||
{{ second }} 秒后返回上一页
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { onUnmounted, ref } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
const props = defineProps({
|
|
||||||
code: String,
|
|
||||||
title: String,
|
|
||||||
showBtn: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let timer: any = null
|
|
||||||
const second = ref(5)
|
|
||||||
const router = useRouter()
|
|
||||||
props.showBtn &&
|
|
||||||
(timer = setInterval(() => {
|
|
||||||
if (second.value === 0) {
|
|
||||||
clearInterval(timer)
|
|
||||||
router.go(-1)
|
|
||||||
} else {
|
|
||||||
second.value--
|
|
||||||
}
|
|
||||||
}, 1000))
|
|
||||||
onUnmounted(() => {
|
|
||||||
timer && clearInterval(timer)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.error {
|
|
||||||
text-align: center;
|
|
||||||
height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
.error-code {
|
|
||||||
@apply text-primary;
|
|
||||||
font-size: 150px;
|
|
||||||
}
|
|
||||||
.el-button {
|
|
||||||
width: 176px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
332
admin/src/views/finance/cash_out.vue
Normal file
332
admin/src/views/finance/cash_out.vue
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main-container">
|
||||||
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
|
|
||||||
|
<el-card class="box-card !border-none my-[16px] table-search-wrap" shadow="never">
|
||||||
|
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
||||||
|
<el-form-item :label="t('cashOutStatus')" prop="order_from">
|
||||||
|
<el-select v-model="orderTableData.searchParam.status" clearable class="input-width">
|
||||||
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
|
<el-option :label="item" :value="key" v-for="(item, key) in cashOutStatusList" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('createTime')" prop="create_time">
|
||||||
|
<el-date-picker v-model="orderTableData.searchParam.create_time" type="datetimerange"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
|
:end-placeholder="t('endDate')" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="loadOrderList()">{{ t('search') }}</el-button>
|
||||||
|
<el-button @click="searchFormRef?.resetFields()">{{ t('reset') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<div class="mt-[16px]">
|
||||||
|
<el-table :data="orderTableData.data" size="large" v-loading="orderTableData.loading">
|
||||||
|
<template #empty>
|
||||||
|
<span>{{ !orderTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table-column prop="order_no" :show-overflow-tooltip="true" :label="t('memberInfo')" align="center" min-width="140">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div class="flex items-center cursor-pointer " @click="toMember(row.member_id)">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.headimg" :src="img(row.headimg)" alt="" >
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/assets/images/default_headimg.png" alt="" >
|
||||||
|
<div class="flex flex flex-col">
|
||||||
|
<span class="text-blue-700">{{ row.nickname || '' }}</span>
|
||||||
|
<span class="text-blue-700">{{ row.mobile || '' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="account_type_name" :label="t('cashOutAccountType')" align="center" min-width="140" />
|
||||||
|
<el-table-column :label="t('cashOutMethod')" align="center" min-width="140" >
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ Transfertype[row.transfer_type].name }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="apply_money" :label="t('applicationForWithdrawalAmount')" min-width="140" align="center" />
|
||||||
|
<!--
|
||||||
|
<el-table-column prop="service_money" :label="t('cashOutCommission')" align="center" min-width="140" />
|
||||||
|
-->
|
||||||
|
<el-table-column prop="money" :label="t('cashOutMoney')" min-width="200" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div>{{ t('actualTransferAmount') }} :{{ row.money }}</div>
|
||||||
|
<div>{{ t('cashOutCommission') }} :{{ row.service_money }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="status_name" :label="t('cashOutStatus')" align="center" min-width="100" />
|
||||||
|
|
||||||
|
<el-table-column :label="t('applyTime')" min-width="180" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.create_time || '' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="t('operation')" fixed="right" width="230">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button v-for="(item,index) in operationBtn[row.status.toString()].value" :key="index+'a'" @click="fnProcessing(operationBtn[row.status.toString()].clickArr[index],row)" type="primary" link>{{ item }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
<div class="mt-[16px] flex justify-end">
|
||||||
|
<el-pagination v-model:current-page="orderTableData.page" v-model:page-size="orderTableData.limit"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper" :total="orderTableData.total"
|
||||||
|
@size-change="loadOrderList()" @current-change="loadOrderList" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 详情 -->
|
||||||
|
<el-dialog v-model="cashOutShowDialog" :title="t('cashOutDetail')" width="500px" :destroy-on-close="true">
|
||||||
|
<el-form :model="cashOutInfo" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="cashOutLoading">
|
||||||
|
<el-form-item :label="t('nickname')">
|
||||||
|
<div class="input-width"> {{ cashOutInfo.nickname }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('cashOutAccountType')">
|
||||||
|
<div class="input-width"> {{ cashOutInfo.account_type_name }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('cashOutMethod')">
|
||||||
|
<div class="input-width"> {{ Transfertype[cashOutInfo.transfer_type].name }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('applicationForWithdrawalAmount')">
|
||||||
|
<div class="input-width"> {{ cashOutInfo.apply_money }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('cashOutCommission')">
|
||||||
|
<div class="input-width"> {{ cashOutInfo.service_money }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('actualTransferAmount')">
|
||||||
|
<div class="input-width"> {{ cashOutInfo.money }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('cashOutStatus')">
|
||||||
|
<div class="input-width"> {{ cashOutInfo.status_name }} </div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="cashOutShowDialog = false">{{t('confirm')}}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 是否审核 -->
|
||||||
|
<el-dialog v-model="auditShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
|
||||||
|
<el-form :model="auditFailure" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||||
|
<el-form-item :label="t('reasonsRefusal')" prop="label_name">
|
||||||
|
<el-input v-model="auditFailure.refuse_reason" clearable :placeholder="t('reasonsRefusalPlaceholder')" class="input-width" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="auditShowDialog = false">{{ t('cancel') }}</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
|
||||||
|
t('confirm')
|
||||||
|
}}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 是否转账 -->
|
||||||
|
<el-dialog v-model="transferShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
|
||||||
|
<p>{{t('isTransfer')}}</p>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="transferShowDialog = false">{{ t('cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="confirm(formRef)">{{
|
||||||
|
t('confirm')
|
||||||
|
}}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import { t } from '@/lang'
|
||||||
|
import { getWithdrawList, getTransfertype, memberTransfer, memberAudit, getWithdrawDetail, getWithdrawStatusList } from '@/api/member'
|
||||||
|
import { img } from '@/utils/common'
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import { data } from 'dom7'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
const cashOutStatusList = ref([])
|
||||||
|
const checkStatusList = async () => {
|
||||||
|
cashOutStatusList.value = await (await getWithdrawStatusList({})).data
|
||||||
|
}
|
||||||
|
checkStatusList()
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const member_id: number = parseInt(route.query.id || 0)
|
||||||
|
const operationBtn = ref({
|
||||||
|
"1": {
|
||||||
|
value: [t('successfulAudit'),t('auditFailure'),t('detail')],
|
||||||
|
clickArr: ['successfulAuditFn','auditFailureFn','detailFn']
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
value: [t('transfer'),t('detail')],
|
||||||
|
clickArr: ['transferFn','detailFn']
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
value: [t('detail')],
|
||||||
|
clickArr: ['detailFn']
|
||||||
|
},
|
||||||
|
"-1": {
|
||||||
|
value: [t('detail')],
|
||||||
|
clickArr: ['detailFn']
|
||||||
|
},
|
||||||
|
"-2": {
|
||||||
|
value: [t('detail')],
|
||||||
|
clickArr: ['detailFn']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const orderTableData = reactive({
|
||||||
|
page: 1,
|
||||||
|
limit: 10,
|
||||||
|
total: 0,
|
||||||
|
loading: true,
|
||||||
|
data: [],
|
||||||
|
searchParam: {
|
||||||
|
order_no: '',
|
||||||
|
member_id,
|
||||||
|
create_time: [],
|
||||||
|
status: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取会员转账方式
|
||||||
|
const Transfertype = ref<Array<Object>>([])
|
||||||
|
const getTransfertypeFn = async()=>{
|
||||||
|
Transfertype.value = await (await getTransfertype()).data
|
||||||
|
}
|
||||||
|
getTransfertypeFn()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取提现列表
|
||||||
|
*/
|
||||||
|
const loadOrderList = (page: number = 1) => {
|
||||||
|
orderTableData.loading = true
|
||||||
|
orderTableData.page = page
|
||||||
|
|
||||||
|
getWithdrawList({
|
||||||
|
page: orderTableData.page,
|
||||||
|
limit: orderTableData.limit,
|
||||||
|
...orderTableData.searchParam
|
||||||
|
}).then(res => {
|
||||||
|
orderTableData.loading = false
|
||||||
|
orderTableData.data = res.data.data
|
||||||
|
orderTableData.total = res.data.total
|
||||||
|
}).catch(() => {
|
||||||
|
orderTableData.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadOrderList()
|
||||||
|
|
||||||
|
// 函数总处理
|
||||||
|
let auditFailure = ref({refuse_reason:'',id:0,action: 0})
|
||||||
|
let auditShowDialog = ref(false);
|
||||||
|
const fnProcessing = (type:string, data: any)=>{
|
||||||
|
let obj = {}
|
||||||
|
if(['successfulAuditFn','auditFailureFn'].includes(type)){
|
||||||
|
obj.id = data.id;
|
||||||
|
if(type == 'successfulAuditFn'){
|
||||||
|
obj.action = 'agree';
|
||||||
|
cashOutAuditFn(obj)
|
||||||
|
}else{
|
||||||
|
obj.action = 'refuse';
|
||||||
|
auditFailure.value = Object.assign(auditFailure.value,obj);
|
||||||
|
auditShowDialog.value = true;
|
||||||
|
}
|
||||||
|
}else if(type == 'transferFn'){
|
||||||
|
obj.id = data.id;
|
||||||
|
ElMessageBox.confirm(`${t('isTransfer')}`,`${t('transfer')}`)
|
||||||
|
.then(() => {
|
||||||
|
transferFn(obj);
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
detailFn(data.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
const transferFn = (data)=>{
|
||||||
|
memberTransfer({...data}).then(res => {
|
||||||
|
loadOrderList()
|
||||||
|
}).catch(() => {
|
||||||
|
loadOrderList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
|
||||||
|
let cashOutShowDialog = ref(false);
|
||||||
|
let cashOutInfo = ref({});
|
||||||
|
let cashOutLoading = ref(true);
|
||||||
|
const detailFn = (id)=>{
|
||||||
|
getWithdrawDetail(id).then(res => {
|
||||||
|
cashOutInfo.value = res.data;
|
||||||
|
cashOutShowDialog.value = true;
|
||||||
|
cashOutLoading.value = false;
|
||||||
|
}).catch(() => {
|
||||||
|
loadOrderList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提现审核
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
const cashOutAuditFn = (data)=>{
|
||||||
|
memberAudit({
|
||||||
|
...data
|
||||||
|
}).then(res => {
|
||||||
|
loadOrderList()
|
||||||
|
}).catch(() => {
|
||||||
|
loadOrderList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拒绝审核
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
const confirm = ()=>{
|
||||||
|
auditShowDialog.value = false;
|
||||||
|
cashOutAuditFn(auditFailure.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单详情
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
const infoEvent = (data: any) => {
|
||||||
|
router.push(`/finance/recharge/detail?order_id=${data.order_id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员详情
|
||||||
|
*/
|
||||||
|
const toMember = (member_id: number) => {
|
||||||
|
router.push(`/member/detail?id=${member_id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
|
|
||||||
<el-card class="box-card !border-none my-[16px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none mb-[16px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
||||||
<!-- <el-form-item :label="t('orderNo')" prop="order_no">
|
<!-- <el-form-item :label="t('orderNo')" prop="order_no">
|
||||||
<el-input v-model="orderTableData.searchParam.order_no" :placeholder="t('orderNoPlaceholder')" />
|
<el-input v-model="orderTableData.searchParam.order_no" :placeholder="t('orderNoPlaceholder')" />
|
||||||
@ -73,9 +73,10 @@
|
|||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="infoEvent(row)">{{ t('info') }}</el-button>
|
<el-button type="primary" link @click="infoEvent(row)">{{ t('info') }}</el-button>
|
||||||
|
|
||||||
|
<el-button v-if="[1, 10].includes(row.order_status_info.status)" type="primary" link @click="refundBtnFn(row)">{{ t('refundBtn') }}</el-button>
|
||||||
|
|
||||||
<template v-for="(item, index) in row.order_status_info.action">
|
<template v-for="(item, index) in row.order_status_info.action">
|
||||||
<el-button type="danger" link @click="orderEvent(row, item.class)">{{ item.name
|
<el-button type="danger" link @click="orderEvent(row, item.class)">{{ item.name }}</el-button>
|
||||||
}}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -87,20 +88,28 @@
|
|||||||
@size-change="loadOrderList()" @current-change="loadOrderList" />
|
@size-change="loadOrderList()" @current-change="loadOrderList" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 是否退款 -->
|
||||||
|
<el-dialog v-model="refundShowDialog" :title="t('refundBtn')" width="500px" :destroy-on-close="true">
|
||||||
|
<p>{{t('refundContent')}}</p>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="refundShowDialog = false">{{ t('cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, watch } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getRechargeOrderStatusList, getRechargeOrderList } from '@/api/order'
|
import { getRechargeOrderStatusList, getRechargeOrderList, rechargeRefund } from '@/api/order'
|
||||||
import { getChannelType } from '@/api/sys'
|
import { getChannelType } from '@/api/sys'
|
||||||
import { img } from '@/utils/common'
|
|
||||||
import { ElMessageBox } from 'element-plus'
|
|
||||||
import { data } from 'dom7'
|
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const member_id: number = parseInt(route.query.id || 0)
|
const member_id: number = parseInt(route.query.id || 0)
|
||||||
@ -169,6 +178,32 @@ const infoEvent = (data: any) => {
|
|||||||
const orderEvent = (data: any, type: string) => {
|
const orderEvent = (data: any, type: string) => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 退款操作
|
||||||
|
*/
|
||||||
|
let refundShowDialog = ref(false);
|
||||||
|
const refundFn = (data) => {
|
||||||
|
console.log("退款操作",data);
|
||||||
|
refundShowDialog.value = true;
|
||||||
|
rechargeRefund(data.order_id).then(res => {
|
||||||
|
refundShowDialog.value = false;
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// getRechargeOrderList({
|
||||||
|
// page: orderTableData.page,
|
||||||
|
// limit: orderTableData.limit,
|
||||||
|
// ...orderTableData.searchParam
|
||||||
|
// }).then(res => {
|
||||||
|
// orderTableData.loading = false
|
||||||
|
// orderTableData.data = res.data.data
|
||||||
|
// orderTableData.total = res.data.total
|
||||||
|
// }).catch(() => {
|
||||||
|
// orderTableData.loading = false
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user