mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-03-27 08:00:43 +00:00
0.0.8
This commit is contained in:
parent
045f63e74d
commit
8916a9662d
1
admin/auto-imports.d.ts
vendored
1
admin/auto-imports.d.ts
vendored
@ -1,6 +1,5 @@
|
|||||||
// Generated by 'unplugin-auto-import'
|
// Generated by 'unplugin-auto-import'
|
||||||
export {}
|
export {}
|
||||||
declare global {
|
declare global {
|
||||||
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
|
||||||
const ElNotification: typeof import('element-plus/es')['ElNotification']
|
const ElNotification: typeof import('element-plus/es')['ElNotification']
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build && node publish.cjs",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
39
admin/publish.cjs
Normal file
39
admin/publish.cjs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const publish = () => {
|
||||||
|
const src = './dist'
|
||||||
|
const dest = '../niucloud/public/admin'
|
||||||
|
|
||||||
|
solve()
|
||||||
|
|
||||||
|
// 目标目录不存在停止复制
|
||||||
|
try {
|
||||||
|
const dir = fs.readdirSync(dest)
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除目标目录下文件
|
||||||
|
fs.rm(dest, { recursive: true }, err => {
|
||||||
|
if(err) {
|
||||||
|
console.log(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.cp(src, dest, { recursive: true }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const solve = () => {
|
||||||
|
const fn = './dist/index.html'
|
||||||
|
const fc = fs.readFileSync(fn, 'utf-8')
|
||||||
|
let text = new String(fc)
|
||||||
|
text = text.replaceAll('./assets/', '/admin/assets/')
|
||||||
|
fs.writeFileSync(fn, text, 'utf8')
|
||||||
|
}
|
||||||
|
|
||||||
|
publish()
|
||||||
@ -4,7 +4,7 @@ import request from '@/utils/request'
|
|||||||
* 获取支付设置
|
* 获取支付设置
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getUserInfo(type: string) {
|
export function getUserInfo() {
|
||||||
return request.get(`auth/get`)
|
return request.get(`auth/get`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -119,8 +119,8 @@ export function deleteSiteGroup(group_id: number) {
|
|||||||
* @param params
|
* @param params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function getSiteGroupAll(params: Record<string, any>) {
|
export function getSiteGroupAll(params: Record<string, any> = {}) {
|
||||||
return request.get(`site/group/all`, params)
|
return request.get(`site/group/all`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************** 当前站点用户 *************************************************/
|
/***************************************************** 当前站点用户 *************************************************/
|
||||||
|
|||||||
@ -675,3 +675,20 @@ export function getAddonList() {
|
|||||||
export function getWapIndexList(params: Record<string, any>) {
|
export function getWapIndexList(params: Record<string, any>) {
|
||||||
return request.get('sys/config/wap_index', { params })
|
return request.get('sys/config/wap_index', { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取开发者key
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getDeveloperToken() {
|
||||||
|
return request.get('sys/config/developer_token')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置开发者key
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function setDeveloperToken(params: Record<string, any>) {
|
||||||
|
return request.put(`sys/config/developer_token`, params, { showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|||||||
@ -175,3 +175,10 @@ export function getGeneratorTableColumn(params: any) {
|
|||||||
export function generatorCheckFile(params: Record<string, any>) {
|
export function generatorCheckFile(params: Record<string, any>) {
|
||||||
return request.get(`generator/check_file`, {params})
|
return request.get(`generator/check_file`, {params})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据模型获取表字段
|
||||||
|
*/
|
||||||
|
export function getGeneratorModelTableColumn(params: any) {
|
||||||
|
return request.get(`generator/model_table_column`, {params})
|
||||||
|
}
|
||||||
|
|||||||
@ -265,4 +265,7 @@ defineExpose({
|
|||||||
.table-head-bg {
|
.table-head-bg {
|
||||||
background-color: var(--el-table-header-bg-color);
|
background-color: var(--el-table-header-bg-color);
|
||||||
}
|
}
|
||||||
|
:deep(.terminal .t-log-box span) {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
<div class="mt-[20px]" v-for="(item, index) in upgradeContent.version_list" :key="index">
|
<div class="mt-[20px]" v-for="(item, index) in upgradeContent.version_list" :key="index">
|
||||||
<div class="font-bold text-lg">{{ item.version_no }}</div>
|
<div class="font-bold text-lg">{{ item.version_no }}</div>
|
||||||
<div class="mt-[5px]">{{ item.release_time }}</div>
|
<div class="mt-[5px]">{{ item.release_time }}</div>
|
||||||
<div class="mt-[10px] p-[10px] rounded bg-[#f4f4f5]" v-if="item.upgrade_log" v-html="item.upgrade_log"></div>
|
<div class="mt-[10px] p-[10px] rounded bg-[#f4f4f5] whitespace-pre" v-if="item.upgrade_log" v-html="item.upgrade_log"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
@ -233,7 +233,7 @@ const open = (addonKey: string = '') => {
|
|||||||
}
|
}
|
||||||
getUpgradeContent(addonKey).then(({ data }) => {
|
getUpgradeContent(addonKey).then(({ data }) => {
|
||||||
upgradeContent.value = data
|
upgradeContent.value = data
|
||||||
if (data.version == data.last_version) {
|
if (!data.version_list.length) {
|
||||||
ElMessage({ message: '已经是最新版本了', type: 'error' })
|
ElMessage({ message: '已经是最新版本了', type: 'error' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -316,4 +316,7 @@ defineExpose({
|
|||||||
.table-head-bg {
|
.table-head-bg {
|
||||||
background-color: var(--el-table-header-bg-color);
|
background-color: var(--el-table-header-bg-color);
|
||||||
}
|
}
|
||||||
|
:deep(.terminal .t-log-box span) {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,25 +1,28 @@
|
|||||||
{
|
{
|
||||||
"menuName": "菜单名称",
|
"menuName": "菜单名称",
|
||||||
"menuType": "类型",
|
"menuType": "类型",
|
||||||
"authId": "权限标识",
|
"authId": "api路径",
|
||||||
"menuTypeDir": "目录",
|
"menuTypeDir": "目录",
|
||||||
"menuTypeMenu": "菜单",
|
"menuTypeMenu": "菜单",
|
||||||
"menuTypeButton": "按钮",
|
"menuTypeButton": "按钮",
|
||||||
"menuDeleteTips": "确定要删除该菜单吗?",
|
"menuDeleteTips": "删除菜单会删除当前菜单以及该菜单下所有子菜单,是否确认删除?",
|
||||||
"addMenu": "添加菜单",
|
"addMenu": "添加菜单",
|
||||||
"updateMenu": "编辑菜单",
|
"updateMenu": "编辑菜单",
|
||||||
"routePath": "路由路径",
|
"routePath": "路由路径",
|
||||||
"viewPath": "组件路径",
|
"viewPath": "组件路径",
|
||||||
|
"addon":"选择应用",
|
||||||
"parentMenu": "父级菜单",
|
"parentMenu": "父级菜单",
|
||||||
"menuIcon": "菜单图标",
|
"menuIcon": "菜单图标",
|
||||||
"sort":"权重",
|
"sort":"权重",
|
||||||
"menuKey":"菜单标识",
|
"menuKey":"权限标识",
|
||||||
"menuNamePlaceholder": "请输入菜单名称",
|
"menuNamePlaceholder": "请输入菜单名称",
|
||||||
"menuKeyPlaceholder": "请输入菜单标识",
|
"menuKeyPlaceholder": "请输入权限标识",
|
||||||
"menuKeyValidata":"菜单标识只能使用字母数字下划线并且开头不能为数字",
|
"menuKeyValidata":"菜单标识只能使用字母数字下划线并且开头不能为数字",
|
||||||
"routePathPlaceholder": "请输入路由路径",
|
"routePathPlaceholder": "请输入路由路径",
|
||||||
"viewPathPlaceholder": "请输入组件路径",
|
"viewPathPlaceholder": "请输入组件路径",
|
||||||
"authIdPlaceholder": "请输入权限标识",
|
"authIdPlaceholder": "请输入api路径",
|
||||||
"selectIconPlaceholder": "请选择菜单图标",
|
"selectIconPlaceholder": "请选择菜单图标",
|
||||||
"topLevel": "顶级"
|
"topLevel": "顶级",
|
||||||
|
"menuShortName":"菜单短标题",
|
||||||
|
"menuShortNamePlaceholder":"请输入菜单短标题"
|
||||||
}
|
}
|
||||||
@ -21,5 +21,10 @@
|
|||||||
"viewPathPlaceholder": "请输入组件路径",
|
"viewPathPlaceholder": "请输入组件路径",
|
||||||
"authIdPlaceholder": "请输入权限标识",
|
"authIdPlaceholder": "请输入权限标识",
|
||||||
"selectIconPlaceholder": "请选择菜单图标",
|
"selectIconPlaceholder": "请选择菜单图标",
|
||||||
"topLevel": "顶级"
|
"topLevel": "顶级",
|
||||||
|
"menuShortName":"菜单短标题",
|
||||||
|
"menuShortNamePlaceholder":"请输入菜单短标题",
|
||||||
|
"addon":"选择应用",
|
||||||
|
"system":"系统菜单",
|
||||||
|
"application":"应用菜单"
|
||||||
}
|
}
|
||||||
5
admin/src/app/lang/zh-cn/setting.developer_token.json
Normal file
5
admin/src/app/lang/zh-cn/setting.developer_token.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"developerTokenEdit":"开发者KEY设置",
|
||||||
|
"tokenPlaceholder":"请输入开发者令牌",
|
||||||
|
"tokenTips": "开发者KEY可以在已安装的框架中设置。框架安装并配置好开发者KEY后,开发者自己开发的应用和插件,会像普通授权插件一样可以安装使用,特别是当开发者发布自己开发的插件或应用时,尚在未发布状态时,开发者也可以对其进行安装测试"
|
||||||
|
}
|
||||||
@ -18,7 +18,9 @@
|
|||||||
"reset": "重置",
|
"reset": "重置",
|
||||||
"search": "搜索",
|
"search": "搜索",
|
||||||
"foldText":"展开/折叠",
|
"foldText":"展开/折叠",
|
||||||
"mainApp": "套餐主应用",
|
"mainApp": "套餐内含应用",
|
||||||
"mainAppPlaceholder": "请选择套餐主应用",
|
"mainAppPlaceholder": "请选择套餐内包含的应用",
|
||||||
"containAddon": "套餐内含插件"
|
"containAddon": "套餐内含插件",
|
||||||
|
"appListEmpty": "没有可选择的应用",
|
||||||
|
"addonListEmpty": "没有可选择的插件"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,6 +131,13 @@
|
|||||||
"setUp":"设置",
|
"setUp":"设置",
|
||||||
"dictType":"数据字典",
|
"dictType":"数据字典",
|
||||||
"dictTypePlaceholder":"请选择数据字典",
|
"dictTypePlaceholder":"请选择数据字典",
|
||||||
"dictTypePlaceholder1":"部分字段未选择数据字典"
|
"dictTypePlaceholder1":"部分字段未选择数据字典",
|
||||||
|
"remotePullDown": "远程下拉",
|
||||||
|
"remotePullDownValue":"远程下拉value字段",
|
||||||
|
"remotePullDownValuePlaceholder":"请选择远程下拉value字段",
|
||||||
|
"remotePullDownLabel":"远程下拉标题字段",
|
||||||
|
"remotePullDownLabelPlaceholder":"请选择远程下拉label字段",
|
||||||
|
"selectType":"下拉类型"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -98,9 +98,9 @@
|
|||||||
<el-card class="box-card !border-none " shadow="never" v-if="!loading">
|
<el-card class="box-card !border-none " shadow="never" v-if="!loading">
|
||||||
<div class="text-[20px] mb-[20px]">历史版本</div>
|
<div class="text-[20px] mb-[20px]">历史版本</div>
|
||||||
<el-timeline>
|
<el-timeline>
|
||||||
<el-timeline-item :timestamp="item.release_time + ' 版本:' + item.version_no" v-for="item in frameworkVersionList" type="primary" :hollow="true" placement="top">
|
<el-timeline-item :timestamp="item['release_time'] + ' 版本:' + item['version_no']" v-for="(item,index) in frameworkVersionList" type="primary" :hollow="true" placement="top" :key="index">
|
||||||
<div class="mt-[10px] p-[20px] bg-overlay rounded-md timeline-log-wrap" v-if="item.upgrade_log">
|
<div class="mt-[10px] p-[20px] bg-overlay rounded-md timeline-log-wrap whitespace-pre" v-if="item['upgrade_log']">
|
||||||
<div v-html="item.upgrade_log"></div>
|
<div v-html="item['upgrade_log']"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-timeline-item>
|
</el-timeline-item>
|
||||||
</el-timeline>
|
</el-timeline>
|
||||||
@ -117,16 +117,13 @@ import { t } from '@/lang'
|
|||||||
import { getVersions } from '@/app/api/auth'
|
import { getVersions } from '@/app/api/auth'
|
||||||
import { getAuthinfo, setAuthinfo, getFrameworkVersionList } from '@/app/api/module'
|
import { getAuthinfo, setAuthinfo, getFrameworkVersionList } from '@/app/api/module'
|
||||||
import { ElMessageBox, FormInstance, FormRules } from 'element-plus'
|
import { ElMessageBox, FormInstance, FormRules } from 'element-plus'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import Upgrade from '@/app/components/upgrade/index.vue'
|
import Upgrade from '@/app/components/upgrade/index.vue'
|
||||||
import CloudBuild from '@/app/components/cloud-build/index.vue'
|
import CloudBuild from '@/app/components/cloud-build/index.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const upgradeRef = ref<any>(null)
|
||||||
const pageName = route.meta.title
|
const cloudBuildRef = ref<any>(null)
|
||||||
const upgradeRef = ref(null)
|
const getAuthCodeDialog: Record<string, any> | null = ref(null)
|
||||||
const cloudBuildRef = ref(null)
|
|
||||||
|
|
||||||
const getAuthCodeDialog = ref(null)
|
|
||||||
const authCodeApproveDialog = ref(false)
|
const authCodeApproveDialog = ref(false)
|
||||||
const isCheck = ref(false)
|
const isCheck = ref(false)
|
||||||
const frameworkVersionList = ref([])
|
const frameworkVersionList = ref([])
|
||||||
@ -138,77 +135,87 @@ const getFrameworkVersionListFn = () => {
|
|||||||
}
|
}
|
||||||
getFrameworkVersionListFn()
|
getFrameworkVersionListFn()
|
||||||
|
|
||||||
const newVersion = computed(() => {
|
const newVersion:any = computed(() => {
|
||||||
return frameworkVersionList.value.length ? frameworkVersionList.value[0] : null
|
return frameworkVersionList.value.length ? frameworkVersionList.value[0] : null
|
||||||
})
|
})
|
||||||
|
|
||||||
const hideAuthCode = (res) => {
|
const hideAuthCode = (res:any) => {
|
||||||
const authCode = JSON.parse(JSON.stringify(res))
|
const authCode = JSON.parse(JSON.stringify(res))
|
||||||
const data = authCode.slice(0, authCode.length / 2) + authCode.slice(authCode.length / 2, authCode.length - 1).replace(/./g, '*')
|
const data = authCode.slice(0, authCode.length / 2) + authCode.slice(authCode.length / 2, authCode.length - 1).replace(/./g, '*')
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
const authCodeApproveFn = () => {
|
const authCodeApproveFn = () => {
|
||||||
authCodeApproveDialog.value = true
|
authCodeApproveDialog.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const authinfo = ref('')
|
interface AuthInfo {
|
||||||
|
company_name: string,
|
||||||
|
site_address: string,
|
||||||
|
auth_code: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const authinfo = ref<AuthInfo>({
|
||||||
|
company_name: '',
|
||||||
|
site_address: '',
|
||||||
|
auth_code: ''
|
||||||
|
})
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const saveLoading = ref(false)
|
const saveLoading = ref(false)
|
||||||
const checkAppMange = () => {
|
const checkAppMange = () => {
|
||||||
getAuthinfo()
|
getAuthinfo()
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
if (res.data.data && res.data.data.length != 0) {
|
if (res.data.data && res.data.data.length != 0) {
|
||||||
authinfo.value = res.data.data
|
authinfo.value = res.data.data
|
||||||
authCodeApproveDialog.value = false
|
authCodeApproveDialog.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
authCodeApproveDialog.value = false
|
authCodeApproveDialog.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkAppMange()
|
checkAppMange()
|
||||||
|
|
||||||
const formData = reactive<Record<string, string>>({
|
const formData = reactive<Record<string, string>>({
|
||||||
auth_code: '',
|
auth_code: '',
|
||||||
auth_secret: ''
|
auth_secret: ''
|
||||||
})
|
})
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
auth_code: [
|
auth_code: [
|
||||||
{ required: true, message: t('authCodePlaceholder'), trigger: 'blur' }
|
{ required: true, message: t('authCodePlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
auth_secret: [
|
auth_secret: [
|
||||||
{ required: true, message: t('authSecretPlaceholder'), trigger: 'blur' }
|
{ required: true, message: t('authSecretPlaceholder'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const save = async (formEl: FormInstance | undefined) => {
|
const save = async (formEl: FormInstance | undefined) => {
|
||||||
if (saveLoading.value || !formEl) return
|
if (saveLoading.value || !formEl) return
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
saveLoading.value = true
|
saveLoading.value = true
|
||||||
|
|
||||||
setAuthinfo(formData)
|
setAuthinfo(formData)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
saveLoading.value = false
|
saveLoading.value = false
|
||||||
checkAppMange()
|
checkAppMange()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
saveLoading.value = false
|
saveLoading.value = false
|
||||||
authCodeApproveDialog.value = false
|
authCodeApproveDialog.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const market = () => {
|
const market = () => {
|
||||||
window.open('https://www.niucloud.com/app')
|
window.open('https://www.niucloud.com/app')
|
||||||
}
|
}
|
||||||
|
|
||||||
const versions = ref('')
|
const versions = ref('')
|
||||||
|
|||||||
@ -1,111 +1,83 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container w-full bg-white" v-loading="loading">
|
<div class="main-container w-full bg-white" v-loading="loading">
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-[20px]">应用管理</span>
|
<span class="text-[20px]">应用管理</span>
|
||||||
<el-form :inline="true" :model="appList.search" ref="searchFormRef">
|
</div>
|
||||||
<el-form-item :label="t('appName')" prop="title">
|
<div class="flex flex-wrap plug-list pb-10 plug-large" v-if="appList.length">
|
||||||
<el-input v-model="appList.search.title" :placeholder="t('appNamePlaceholder')" />
|
<div v-for="(item, index) in appList" :key="index + 'b'">
|
||||||
</el-form-item>
|
<div
|
||||||
<el-form-item>
|
class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary">
|
||||||
<el-button type="primary" @click="getAppList()">{{ t('search') }}</el-button>
|
<div @click="toLink(item.key)" class="flex py-5 items-center">
|
||||||
</el-form-item>
|
<div class="flex justify-center items-center">
|
||||||
</el-form>
|
<el-image class="w-[40px] h-[40px]" :src="img(item.icon)" fit="contain">
|
||||||
</div>
|
<template #error>
|
||||||
<div class="flex flex-wrap plug-list pb-10 plug-large" v-if="appList.list.length">
|
<div class="image-slot">
|
||||||
<div v-for="(item, index) in appList.list" :key="index + 'b'">
|
<img class="w-[50px] h-[50px]"
|
||||||
<div
|
src="@/app/assets/images/index/app_default.png" />
|
||||||
class="relative app-item cursor-pointer px-4 mr-4 mt-[20px] bg-[#f7f7f7] border-[1px] hover:border-primary">
|
</div>
|
||||||
<div @click="toLink(item.key)" class="flex py-5 items-center">
|
</template>
|
||||||
<div class="flex justify-center items-center">
|
</el-image>
|
||||||
<el-image class="w-[40px] h-[40px]" :src="img(item.icon)" fit="contain">
|
</div>
|
||||||
<template #error>
|
<div class="flex flex-col justify-between text-left w-[190px]">
|
||||||
<div class="image-slot">
|
<p class="app-text w-[190px] text-[17px] text-[#222] pl-3">{{ item.title }}</p>
|
||||||
<img class="w-[50px] h-[50px]"
|
</div>
|
||||||
src="@/app/assets/images/index/app_default.png" />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</el-image>
|
</div>
|
||||||
</div>
|
<div class="empty flex items-center justify-center" v-if="!loading && !appList.length">
|
||||||
<div class="flex flex-col justify-between text-left w-[190px]">
|
<el-empty :description="t('emptyAppData')" />
|
||||||
<p class="app-text w-[190px] text-[17px] text-[#222] pl-3">{{ item.title }}</p>
|
</div>
|
||||||
</div>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="empty flex items-center justify-center" v-if="!loading && !appList.list.length">
|
|
||||||
<el-empty :description="t('emptyAppData')" />
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { getSiteAddons } from '@/app/api/site'
|
import { getSiteAddons } from '@/app/api/site'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { findFirstValidRoute } from '@/router/routers'
|
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const addonIndexRoute = useUserStore().addonIndexRoute
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const appList = reactive({
|
const appList = ref<Record<string, any>[]>([])
|
||||||
list: [],
|
|
||||||
search: {
|
|
||||||
title: ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const getAppList = async () => {
|
const getAppList = async () => {
|
||||||
const res = await getSiteAddons({ title: appList.search.title })
|
const res = await getSiteAddons()
|
||||||
appList.list = res.data
|
appList.value = res.data
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
getAppList()
|
||||||
const appLink = ref({})
|
|
||||||
const getAppLink = () => {
|
|
||||||
userStore.routers.forEach((item, index) => {
|
|
||||||
if (item.meta.addon != '') {
|
|
||||||
if (item.children && item.children.length) {
|
|
||||||
appLink.value[item.meta.addon] = findFirstValidRoute(item.children)
|
|
||||||
} else {
|
|
||||||
appLink.value[item.meta.addon] = item.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
getAppList()
|
|
||||||
}
|
|
||||||
getAppLink()
|
|
||||||
|
|
||||||
const toLink = (addon: string) => {
|
const toLink = (addon: string) => {
|
||||||
appLink.value[addon] && router.push({ name: appLink.value[addon] })
|
addonIndexRoute[addon] && router.push({ name: addonIndexRoute[addon] })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.main-container,
|
.main-container,
|
||||||
.empty {
|
.empty {
|
||||||
min-height: calc(100vh - 84px);
|
min-height: calc(100vh - 84px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-text {
|
.app-text {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
/* 超出部分隐藏 */
|
/* 超出部分隐藏 */
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* 禁止文本换行 */
|
/* 禁止文本换行 */
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
/* 显示省略号 */
|
/* 显示省略号 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-item:hover .with-ite {
|
.app-item:hover .with-ite {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item {
|
.el-form-item {
|
||||||
margin-bottom: 0px !important;
|
margin-bottom: 0px !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div class="flex justify-between items-center h-[32px] mb-4">
|
<div class="flex justify-between items-center h-[32px] mb-4">
|
||||||
<span class="text-[26px] text-[#222] font-600">{{ t('localAppText') }}</span>
|
<span class="text-[26px] text-[#222] font-600">{{ t('localAppText') }}</span>
|
||||||
<div class="w-[247px]">
|
<div class="w-[247px]">
|
||||||
<el-input :placeholder="t('search')" v-model="search_name" @keyup.enter="query">
|
<el-input :placeholder="t('search')" v-model="searchName" @keyup.enter="query">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<el-icon class="el-input__icon cursor-pointer" size="14px" @click="query">
|
<el-icon class="el-input__icon cursor-pointer" size="14px" @click="query">
|
||||||
<search />
|
<search />
|
||||||
@ -15,18 +15,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex mt-[24px]">
|
<div class="flex mt-[24px]">
|
||||||
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'installed' }"
|
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'installed' }"
|
||||||
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
|
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
|
||||||
@click="activeName = 'installed'">
|
@click="activeName = 'installed'">
|
||||||
{{ t('installLabel') }}
|
{{ t('installLabel') }}
|
||||||
</div>
|
</div>
|
||||||
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'uninstalled' }"
|
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'uninstalled' }"
|
||||||
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
|
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
|
||||||
@click="activeName = 'uninstalled'">
|
@click="activeName = 'uninstalled'">
|
||||||
{{ t('uninstalledLabel') }}
|
{{ t('uninstalledLabel') }}
|
||||||
</div>
|
</div>
|
||||||
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'all' }"
|
<div :class="{ '!bg-[#000] !border-0 !text-[#fff]': activeName === 'all' }"
|
||||||
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
|
class="w-[78px] h-[30rpx] text-[14px] text-[#242424] text-center rounded-[15px] leading-[30px] bg-[#F0F0F0] border-solid border-1 border-[#E0E0E0] cursor-pointer mr-[24px]"
|
||||||
@click="activeName = 'all'">
|
@click="activeName = 'all'">
|
||||||
{{ t('buyLabel') }}
|
{{ t('buyLabel') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,8 +35,8 @@
|
|||||||
<el-table-column :label="t('appName')" align="left" width="320">
|
<el-table-column :label="t('appName')" align="left" width="320">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center"
|
<div class="flex items-center"
|
||||||
:class="{ 'cursor-pointer': row.type == 'app' && Object.keys(row.install_info).length }"
|
:class="{ 'cursor-pointer': row.type == 'app' && Object.keys(row.install_info).length }"
|
||||||
@click="itemPath(row)">
|
@click="itemPath(row)">
|
||||||
<el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain">
|
<el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<img class="w-[54px] h-[54px]" src="@/app/assets/images/icon-addon.png" alt="">
|
<img class="w-[54px] h-[54px]" src="@/app/assets/images/icon-addon.png" alt="">
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<el-table-column :label="t('type')" align="left" min-width="100">
|
<el-table-column :label="t('type')" align="left" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span class="text-[#222] font-500 text-[13px]">{{ row.type === 'app' ? t('app') : t('addon')
|
<span class="text-[#222] font-500 text-[13px]">{{ row.type === 'app' ? t('app') : t('addon')
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="" :label="t('author')" align="left" min-width="100">
|
<el-table-column prop="" :label="t('author')" align="left" min-width="100">
|
||||||
@ -84,21 +84,21 @@
|
|||||||
<el-table-column :label="t('operation')" fixed="right" align="right" width="150">
|
<el-table-column :label="t('operation')" fixed="right" align="right" width="150">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button class="!text-[13px]" type="primary" link @click="getAddonDetialFn(row)">{{
|
<el-button class="!text-[13px]" type="primary" link @click="getAddonDetialFn(row)">{{
|
||||||
t('detail') }}</el-button>
|
t('detail') }}</el-button>
|
||||||
<el-button class="!text-[13px]" v-if="row.install_info && Object.keys(row.install_info)?.length"
|
<el-button class="!text-[13px]" v-if="row.install_info && Object.keys(row.install_info)?.length"
|
||||||
type="primary" link @click="uninstallAddonFn(row.key)">{{ t('unload') }}</el-button>
|
type="primary" link @click="uninstallAddonFn(row.key)">{{ t('unload') }}</el-button>
|
||||||
|
|
||||||
<el-button class="!text-[13px]" v-else-if="row.is_download && row.install_info <= 0"
|
<el-button class="!text-[13px]" v-else-if="row.is_download && row.install_info <= 0"
|
||||||
type="primary" link @click="installAddonFn(row.key)">{{ t('install')
|
type="primary" link @click="installAddonFn(row.key)">{{ t('install')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
<el-button class="!text-[13px]" v-else :loading="downloading == row.key"
|
<el-button class="!text-[13px]" v-else :loading="downloading == row.key"
|
||||||
:disabled="downloading != ''" type="primary" link @click.stop="downEvent(row)">{{
|
:disabled="downloading != ''" type="primary" link @click.stop="downEvent(row)">{{
|
||||||
t('down') }}</el-button>
|
t('down') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-empty class="mx-auto overview-empty"
|
<el-empty class="mx-auto overview-empty"
|
||||||
v-if="!localList.installed.length && !loading && activeName == 'installed'">
|
v-if="!localList.installed.length && !loading && activeName == 'installed'">
|
||||||
<template #image>
|
<template #image>
|
||||||
<div class="w-[230px] mx-auto">
|
<div class="w-[230px] mx-auto">
|
||||||
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
|
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
|
||||||
@ -109,7 +109,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-empty>
|
</el-empty>
|
||||||
<el-empty class="mx-auto overview-empty"
|
<el-empty class="mx-auto overview-empty"
|
||||||
v-if="!localList.uninstalled.length && !loading && activeName == 'uninstalled'">
|
v-if="!localList.uninstalled.length && !loading && activeName == 'uninstalled'">
|
||||||
<template #image>
|
<template #image>
|
||||||
<div class="w-[230px] mx-auto">
|
<div class="w-[230px] mx-auto">
|
||||||
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
|
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
|
||||||
@ -124,20 +124,20 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-empty>
|
</el-empty>
|
||||||
<div v-if="!localList.all.length && !loading && !authinfo && activeName == 'all'"
|
<div v-if="!localList.all.length && !loading && !authinfo && activeName == 'all'"
|
||||||
class="mx-auto overview-empty flex flex-col items-center pt-14 pb-6">
|
class="mx-auto overview-empty flex flex-col items-center pt-14 pb-6">
|
||||||
<div class="mb-[20px] text-sm text-[#888]">检测到当前账号尚未绑定授权,请先绑定授权!</div>
|
<div class="mb-[20px] text-sm text-[#888]">检测到当前账号尚未绑定授权,请先绑定授权!</div>
|
||||||
<div class="flex flex-1 flex-wrap justify-center relative">
|
<div class="flex flex-1 flex-wrap justify-center relative">
|
||||||
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary"
|
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary"
|
||||||
@click="authCodeApproveFn">授权码认证</el-button>
|
@click="authCodeApproveFn">授权码认证</el-button>
|
||||||
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click"
|
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click"
|
||||||
class="mt-[8px]">
|
class="mt-[8px]">
|
||||||
<div class="px-[18px] py-[8px]">
|
<div class="px-[18px] py-[8px]">
|
||||||
<p class="leading-[32px] text-[14px]">
|
<p class="leading-[32px] text-[14px]">
|
||||||
您在官方应用市场购买任意一款应用,即可获得授权码。输入正确授权码认证通过后,即可支持在线升级和其它相关服务</p>
|
您在官方应用市场购买任意一款应用,即可获得授权码。输入正确授权码认证通过后,即可支持在线升级和其它相关服务</p>
|
||||||
<div class="flex justify-end mt-[36px]">
|
<div class="flex justify-end mt-[36px]">
|
||||||
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
|
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
|
||||||
<el-button class="w-[100px] !h-[48px]" plain
|
<el-button class="w-[100px] !h-[48px]" plain
|
||||||
@click="getAuthCodeDialog.hide()">关闭</el-button>
|
@click="getAuthCodeDialog.hide()">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
@ -154,13 +154,13 @@
|
|||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-form-item prop="auth_code">
|
<el-form-item prop="auth_code">
|
||||||
<el-input v-model="formData.auth_code" :placeholder="t('authCodePlaceholder')"
|
<el-input v-model="formData.auth_code" :placeholder="t('authCodePlaceholder')"
|
||||||
class="input-width" clearable size="large" />
|
class="input-width" clearable size="large" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<div class="mt-[20px]">
|
<div class="mt-[20px]">
|
||||||
<el-form-item prop="auth_secret">
|
<el-form-item prop="auth_secret">
|
||||||
<el-input v-model="formData.auth_secret" clearable :placeholder="t('authSecretPlaceholder')"
|
<el-input v-model="formData.auth_secret" clearable :placeholder="t('authSecretPlaceholder')"
|
||||||
class="input-width" size="large" />
|
class="input-width" size="large" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -168,7 +168,7 @@
|
|||||||
|
|
||||||
<div class="mt-[20px]">
|
<div class="mt-[20px]">
|
||||||
<el-button type="primary" class="w-full" size="large" :loading="saveLoading"
|
<el-button type="primary" class="w-full" size="large" :loading="saveLoading"
|
||||||
@click="save(formRef)">{{ t('confirm') }}</el-button>
|
@click="save(formRef)">{{ t('confirm') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[10px] text-right">
|
<div class="mt-[10px] text-right">
|
||||||
<el-button type="primary" link @click="market">{{ t('notHaveAuth') }}</el-button>
|
<el-button type="primary" link @click="market">{{ t('notHaveAuth') }}</el-button>
|
||||||
@ -201,7 +201,7 @@
|
|||||||
|
|
||||||
<!-- 安装弹窗 -->
|
<!-- 安装弹窗 -->
|
||||||
<el-dialog v-model="installShowDialog" :title="t('addonInstall')" width="850px" :close-on-click-modal="false"
|
<el-dialog v-model="installShowDialog" :title="t('addonInstall')" width="850px" :close-on-click-modal="false"
|
||||||
:close-on-press-escape="false" :before-close="installShowDialogClose">
|
:close-on-press-escape="false" :before-close="installShowDialogClose">
|
||||||
<el-steps :space="200" :active="installStep" finish-status="success" align-center>
|
<el-steps :space="200" :active="installStep" finish-status="success" align-center>
|
||||||
<el-step :title="t('envCheck')" class="flex-1" />
|
<el-step :title="t('envCheck')" class="flex-1" />
|
||||||
<el-step :title="t('installProgress')" class="flex-1" />
|
<el-step :title="t('installProgress')" class="flex-1" />
|
||||||
@ -225,7 +225,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]"
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
v-for="item in installCheckResult.dir.is_readable">
|
v-for="(item, index) in installCheckResult.dir.is_readable" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -242,7 +242,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]"
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
v-for="item in installCheckResult.dir.is_write">
|
v-for="(item, index) in installCheckResult.dir.is_write" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -265,13 +265,13 @@
|
|||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<el-tooltip effect="dark" :content="t('installTips')" placement="top">
|
<el-tooltip effect="dark" :content="t('installTips')" placement="top">
|
||||||
<el-button type="default" :disabled="!installCheckResult.is_pass || cloudInstalling"
|
<el-button type="default" :disabled="!installCheckResult.is_pass || cloudInstalling"
|
||||||
:loading="localInstalling" @click="handleInstall">{{
|
:loading="localInstalling" @click="handleInstall">{{
|
||||||
t('localInstall')
|
t('localInstall')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="dark" :content="t('cloudInstallTips')" placement="top">
|
<el-tooltip effect="dark" :content="t('cloudInstallTips')" placement="top">
|
||||||
<el-button type="primary" :disabled="!installCheckResult.is_pass || localInstalling"
|
<el-button type="primary" :disabled="!installCheckResult.is_pass || localInstalling"
|
||||||
:loading="cloudInstalling" @click="handleCloudInstall">{{
|
:loading="cloudInstalling" @click="handleCloudInstall">{{
|
||||||
t('cloudInstall')
|
t('cloudInstall')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@ -279,19 +279,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-show="installStep == 2" class="h-[50vh] mt-[20px]">
|
<div v-show="installStep == 2" class="h-[50vh] mt-[20px]">
|
||||||
<terminal name="my-terminal" :context="currAddon" :init-log="null" :show-header="false"
|
<terminal name="my-terminal" :context="currAddon" :init-log="null" :show-header="false"
|
||||||
:show-log-time="true" />
|
:show-log-time="true" />
|
||||||
</div>
|
</div>
|
||||||
<div v-show="installStep == 3" class="h-[50vh] mt-[20px] flex flex-col">
|
<div v-show="installStep == 3" class="h-[50vh] mt-[20px] flex flex-col">
|
||||||
<el-result icon="success" :title="t('addonInstallSuccess')"></el-result>
|
<el-result icon="success" :title="t('addonInstallSuccess')"></el-result>
|
||||||
<!-- 提示信息 -->
|
<!-- 提示信息 -->
|
||||||
<div v-for="item in installAfterTips" class="mb-[10px]">
|
<div v-for="(item, index) in installAfterTips" class="mb-[10px]" :key="index">
|
||||||
<el-alert :title="item" type="error" :closable="false" />
|
<el-alert :title="item" type="error" :closable="false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-model="uninstallShowDialog" :title="t('addonUninstall')" width="850px"
|
<el-dialog v-model="uninstallShowDialog" :title="t('addonUninstall')" width="850px"
|
||||||
:close-on-click-modal="false" :close-on-press-escape="false">
|
:close-on-click-modal="false" :close-on-press-escape="false">
|
||||||
<el-scrollbar max-height="50vh">
|
<el-scrollbar max-height="50vh">
|
||||||
<div class="min-h-[150px]">
|
<div class="min-h-[150px]">
|
||||||
<div class="bg-[#fff] my-3" v-if="uninstallCheckResult.dir">
|
<div class="bg-[#fff] my-3" v-if="uninstallCheckResult.dir">
|
||||||
@ -309,7 +309,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]"
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
v-for="item in uninstallCheckResult.dir.is_readable">
|
v-for="(item, index) in uninstallCheckResult.dir.is_readable" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -325,7 +325,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]" v-for="item in uninstallCheckResult.dir.is_write">
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
|
v-for="(item, index) in uninstallCheckResult.dir.is_write" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -355,20 +356,22 @@ import { ref, reactive, watch, h } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck, cancelInstall } from '@/app/api/addon'
|
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck, cancelInstall } from '@/app/api/addon'
|
||||||
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
|
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
|
||||||
import { ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus'
|
import { ElMessageBox, ElNotification, FormInstance, FormRules, NotificationHandle } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
// import { img } from '@/utils/common'
|
||||||
import { Terminal, api as terminalApi } from 'vue-web-terminal'
|
import { Terminal, api as terminalApi } from 'vue-web-terminal'
|
||||||
import { findFirstValidRoute } from '@/router/routers'
|
import { findFirstValidRoute } from '@/router/routers'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const activeName = ref('installed')
|
const activeName = ref('installed')
|
||||||
|
|
||||||
const loading = ref<Boolean>(true)
|
const loading = ref<Boolean>(true)
|
||||||
const downloading = ref('')
|
const downloading = ref('')
|
||||||
const installAfterTips = ref<string[]>([])
|
const installAfterTips = ref<string[]>([])
|
||||||
const userStore = useUserStore()
|
const userStore: any = useUserStore()
|
||||||
|
|
||||||
const downEvent = (param: Record<string, any>) => {
|
const downEvent = (param: Record<string, any>) => {
|
||||||
if (downloading.value) return
|
if (downloading.value) return
|
||||||
@ -395,25 +398,29 @@ getAuthinfo().then(res => {
|
|||||||
* 本地下载的插件列表
|
* 本地下载的插件列表
|
||||||
*/
|
*/
|
||||||
// input 筛选
|
// input 筛选
|
||||||
const search_name = ref('')
|
const searchName = ref('')
|
||||||
// 表格展示数据
|
// 表格展示数据
|
||||||
const info = ref({
|
const info:AnyObject = ref<{
|
||||||
|
installed: never[];
|
||||||
|
uninstalled: never[];
|
||||||
|
all: never[];
|
||||||
|
}>({
|
||||||
installed: [],
|
installed: [],
|
||||||
uninstalled: [],
|
uninstalled: [],
|
||||||
all: []
|
all: []
|
||||||
})
|
})
|
||||||
const query = () => {
|
const query = () => {
|
||||||
if (search_name.value == '' || search_name.value == null) {
|
if (searchName.value == '' || searchName.value == null) {
|
||||||
info.value.installed = localList.value.installed
|
info.value.installed = localList.value.installed
|
||||||
info.value.uninstalled = localList.value.uninstalled
|
info.value.uninstalled = localList.value.uninstalled
|
||||||
info.value.all = localList.value.all
|
info.value.all = localList.value.all
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
info.value.installed = localList.value.installed.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
info.value.installed = localList.value.installed.filter((el: any) => el.title.indexOf(searchName.value) != -1)
|
||||||
info.value.uninstalled = localList.value.uninstalled.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
info.value.uninstalled = localList.value.uninstalled.filter((el: any) => el.title.indexOf(searchName.value) != -1)
|
||||||
info.value.all = localList.value.all.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
info.value.all = localList.value.all.filter((el: any) => el.title.indexOf(searchName.value) != -1)
|
||||||
}
|
}
|
||||||
const localList = ref({
|
const localList:AnyObject = ref({
|
||||||
installed: [],
|
installed: [],
|
||||||
uninstalled: [],
|
uninstalled: [],
|
||||||
all: [],
|
all: [],
|
||||||
@ -423,7 +430,7 @@ const localList = ref({
|
|||||||
const localListFn = () => {
|
const localListFn = () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
getAddonLocal({}).then(res => {
|
getAddonLocal({}).then(res => {
|
||||||
const data = res.data.list
|
const data:any = res.data.list
|
||||||
localList.value.error = res.data.error
|
localList.value.error = res.data.error
|
||||||
localList.value.installed = []
|
localList.value.installed = []
|
||||||
localList.value.uninstalled = []
|
localList.value.uninstalled = []
|
||||||
@ -438,7 +445,7 @@ const localListFn = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
query()
|
query()
|
||||||
userStore.routers.forEach((item, index) => {
|
userStore.routers.forEach((item:AnyObject, index:number) => {
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
item.name = findFirstValidRoute(item.children)
|
item.name = findFirstValidRoute(item.children)
|
||||||
appLink.value[item.meta.app] = findFirstValidRoute(item.children)
|
appLink.value[item.meta.app] = findFirstValidRoute(item.children)
|
||||||
@ -478,7 +485,7 @@ const installShowDialog = ref(false)
|
|||||||
const installStep = ref(1)
|
const installStep = ref(1)
|
||||||
|
|
||||||
// 安装检测结果
|
// 安装检测结果
|
||||||
const installCheckResult = ref({})
|
const installCheckResult = ref<AnyObject>({})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安装
|
* 安装
|
||||||
@ -499,7 +506,7 @@ const installAddonFn = (key: string) => {
|
|||||||
/**
|
/**
|
||||||
* 获取正在进行的安装任务
|
* 获取正在进行的安装任务
|
||||||
*/
|
*/
|
||||||
let notificationEl = null
|
let notificationEl: NotificationHandle | null | any = null
|
||||||
const getInstallTask = (first: boolean = true) => {
|
const getInstallTask = (first: boolean = true) => {
|
||||||
getAddonInstalltask().then(res => {
|
getAddonInstalltask().then(res => {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
@ -614,7 +621,7 @@ const getCloudInstallLog = () => {
|
|||||||
.then(res => {
|
.then(res => {
|
||||||
const data = res.data.data ?? []
|
const data = res.data.data ?? []
|
||||||
if (data[0] && data[0].length && installShowDialog.value == true) {
|
if (data[0] && data[0].length && installShowDialog.value == true) {
|
||||||
data[0].forEach(item => {
|
data[0].forEach((item: { action: string; code: number; msg: any }) => {
|
||||||
if (!installLog.includes(item.action)) {
|
if (!installLog.includes(item.action)) {
|
||||||
terminalApi.pushMessage('my-terminal', { content: `正在执行:${item.action}` })
|
terminalApi.pushMessage('my-terminal', { content: `正在执行:${item.action}` })
|
||||||
installLog.push(item.action)
|
installLog.push(item.action)
|
||||||
@ -639,7 +646,7 @@ watch(currAddon, (nval) => {
|
|||||||
const uninstallShowDialog = ref(false)
|
const uninstallShowDialog = ref(false)
|
||||||
|
|
||||||
// 卸载环境检测结果
|
// 卸载环境检测结果
|
||||||
const uninstallCheckResult = ref({})
|
const uninstallCheckResult = ref<AnyObject>({})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 卸载
|
* 卸载
|
||||||
@ -698,7 +705,7 @@ const getAddonDetialFn = (data: AnyObject) => {
|
|||||||
// 授权
|
// 授权
|
||||||
const authCodeApproveDialog = ref(false)
|
const authCodeApproveDialog = ref(false)
|
||||||
const authinfo = ref('')
|
const authinfo = ref('')
|
||||||
const getAuthCodeDialog = ref(null)
|
const getAuthCodeDialog: Record<string, any> | null = ref(null)
|
||||||
const saveLoading = ref(false)
|
const saveLoading = ref(false)
|
||||||
const checkAppMange = () => {
|
const checkAppMange = () => {
|
||||||
getAuthinfo()
|
getAuthinfo()
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||||
<el-form :model="formData" label-width="90px" class="page-form" ref="formRef" :rules="formRules" v-loading="loading">
|
<el-form :model="formData" label-width="90px" class="page-form" ref="formRef" :rules="formRules"
|
||||||
|
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>
|
||||||
@ -16,13 +17,21 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('parentMenu')" prop="parent_key">
|
<el-form-item :label="t('addon')" prop="addon" v-show="formData.app_type == 'site'">
|
||||||
<el-select v-model="formData.parent_key" placeholder="Select" class="input-width">
|
<el-select v-model="formData.addon" placeholder="Select" class="input-width" @change="addonChange">
|
||||||
<el-option :label="t('topLevel')" value="" />
|
<el-option v-for="(item, index) in addonLst" :label="item.title" :value="item.key" :key="index" />
|
||||||
<select-menu-item :menu="item" v-for="(item, index) in prop.menuTree" :key="index" />
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label="t('parentMenu')" prop="parent_key">
|
||||||
|
<el-tree-select class="input-width" v-if="formData.addon != ''" v-model="formData.parent_key"
|
||||||
|
:props="{ label: 'menu_name', value: 'menu_key' }" :data="addonMenuList" check-strictly
|
||||||
|
:render-after-expand="false" />
|
||||||
|
<el-tree-select class="input-width" v-else v-model="formData.parent_key"
|
||||||
|
:props="{ label: 'menu_name', value: 'menu_key' }" :data="sysMenuList" check-strictly
|
||||||
|
:render-after-expand="false" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('routePath')" prop="router_path" v-show="formData.menu_type != 2">
|
<el-form-item :label="t('routePath')" prop="router_path" v-show="formData.menu_type != 2">
|
||||||
<el-input v-model="formData.router_path" :placeholder="t('routePathPlaceholder')" class="input-width" />
|
<el-input v-model="formData.router_path" :placeholder="t('routePathPlaceholder')" class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -34,7 +43,7 @@
|
|||||||
<el-form-item :label="t('authId')" prop="api_url" v-show="formData.menu_type != 0">
|
<el-form-item :label="t('authId')" prop="api_url" v-show="formData.menu_type != 0">
|
||||||
<el-input v-model="formData.api_url" :placeholder="t('authIdPlaceholder')" class="input-width">
|
<el-input v-model="formData.api_url" :placeholder="t('authIdPlaceholder')" class="input-width">
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-select class="w-[90px] border-none" v-model="method">
|
<el-select class="w-[90px] border-none" v-model="formData.methods">
|
||||||
<el-option label="POST" value="post" />
|
<el-option label="POST" value="post" />
|
||||||
<el-option label="GET" value="get" />
|
<el-option label="GET" value="get" />
|
||||||
<el-option label="PUT" value="put" />
|
<el-option label="PUT" value="put" />
|
||||||
@ -64,6 +73,11 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label="t('menuShortName')">
|
||||||
|
<el-input v-model="formData.menu_short_name" :placeholder="t('menuShortNamePlaceholder')"
|
||||||
|
class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('sort')">
|
<el-form-item :label="t('sort')">
|
||||||
<el-input-number v-model="formData.sort" :min="0" />
|
<el-input-number v-model="formData.sort" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -72,7 +86,7 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{t('confirm')}}</el-button>
|
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -82,13 +96,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 selectMenuItem from './select-menu-item.vue'
|
import { addMenu, editMenu, getMenuInfo, getSystemMenu, getAddonMenu } from '@/app/api/sys'
|
||||||
import { addMenu, editMenu, getMenuInfo } from '@/app/api/sys'
|
import { getAddonDevelop } from '@/app/api/tools'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const method = ref('post')
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
let popTitle: string = '';
|
let popTitle: string = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
@ -102,22 +115,20 @@ const initialFormData = {
|
|||||||
api_url: '',
|
api_url: '',
|
||||||
router_path: '',
|
router_path: '',
|
||||||
view_path: '',
|
view_path: '',
|
||||||
methods: '',
|
methods: 'post',
|
||||||
sort: '',
|
sort: '',
|
||||||
status: 1,
|
status: 1,
|
||||||
is_show: 1,
|
is_show: 1,
|
||||||
menu_key: '',
|
menu_key: '',
|
||||||
app_type: ''
|
app_type: '',
|
||||||
|
addon: '',
|
||||||
|
menu_short_name: ''
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
const prop = defineProps({
|
const addonLst = ref<Array<any>>([])
|
||||||
menuTree: {
|
const sysMenuList = ref<Array<any>>([])
|
||||||
type: Array,
|
const addonMenuList = ref<Array<any>>([])
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
const validataMenuKey = (val: string) => {
|
const validataMenuKey = (val: string) => {
|
||||||
@ -143,7 +154,7 @@ const formRules = computed(() => {
|
|||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
//return /^([a-zA-Z_$])([a-zA-Z0-9_$])*$/.test(val)
|
// return /^([a-zA-Z_$])([a-zA-Z0-9_$])*$/.test(val)
|
||||||
router_path: [
|
router_path: [
|
||||||
{ required: formData.menu_type != 2, message: t('routePathPlaceholder'), trigger: 'blur' }
|
{ required: formData.menu_type != 2, message: t('routePathPlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
@ -154,11 +165,40 @@ const formRules = computed(() => {
|
|||||||
{ required: formData.menu_type != 2, message: t('selectIconPlaceholder'), trigger: 'blur' }
|
{ required: formData.menu_type != 2, message: t('selectIconPlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
api_url: [
|
api_url: [
|
||||||
{ required: formData.menu_type == 2, message: t('selectIconPlaceholder'), trigger: 'blur' }
|
{ required: formData.menu_type == 2, message: t('authIdPlaceholder'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 获取插件列表
|
||||||
|
const getAddonDevelopFn = async () => {
|
||||||
|
const { data } = await getAddonDevelop({})
|
||||||
|
addonLst.value = [{ title: '系统', key: '' }]
|
||||||
|
addonLst.value.push(...data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取系统菜单列表
|
||||||
|
const getSystemMenuFn = async () => {
|
||||||
|
const { data } = await getSystemMenu()
|
||||||
|
sysMenuList.value = [{ menu_name: '顶级', menu_key: '' }]
|
||||||
|
sysMenuList.value.push(...data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取系统应用列表
|
||||||
|
const getAddonMenuFn = async (key: any) => {
|
||||||
|
const { data } = await getAddonMenu(key)
|
||||||
|
addonMenuList.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择应用
|
||||||
|
const addonChange = async (val: any) => {
|
||||||
|
formData.parent_key = ''
|
||||||
|
if (val != '') {
|
||||||
|
await getAddonMenuFn(val)
|
||||||
|
formData.parent_key = addonMenuList.value[0].menu_key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +214,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
const data = formData
|
const data = formData
|
||||||
data.api_url = data.api_url ? `${data.api_url}/${method.value}` : ''
|
data.api_url = data.api_url ? `${data.api_url}/${formData.methods}` : ''
|
||||||
|
|
||||||
save(data).then(res => {
|
save(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@ -182,7 +222,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -192,17 +231,21 @@ const setFormData = async (row: any = null) => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
popTitle = t('addMenu')
|
popTitle = t('addMenu')
|
||||||
|
getAddonDevelopFn()
|
||||||
|
getSystemMenuFn()
|
||||||
if (row.menu_key) {
|
if (row.menu_key) {
|
||||||
popTitle = t('updateMenu')
|
popTitle = t('updateMenu')
|
||||||
const data = await (await getMenuInfo(row.menu_key)).data
|
const data = await (await getMenuInfo(row.app_type, row.menu_key)).data
|
||||||
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]
|
||||||
})
|
})
|
||||||
|
if (formData.addon != '') getAddonMenuFn(formData.addon)
|
||||||
} 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]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ const showDialog = ref(false)
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const isOpen = ref(true)
|
const isOpen = ref(true)
|
||||||
|
|
||||||
let popTitle: string = '';
|
let popTitle: string = ''
|
||||||
|
|
||||||
// 获取权限数据
|
// 获取权限数据
|
||||||
const menus = ref<Record<string, any>[]>([])
|
const menus = ref<Record<string, any>[]>([])
|
||||||
@ -55,7 +55,6 @@ getSiteMenus().then((res) => {
|
|||||||
menus.value = res.data
|
menus.value = res.data
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 全选
|
// 全选
|
||||||
const selectAll = ref(false)
|
const selectAll = ref(false)
|
||||||
const checkStrictly = ref(false)
|
const checkStrictly = ref(false)
|
||||||
@ -73,28 +72,27 @@ const handleCheckChange = debounce((e) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const menuAction = () => {
|
const menuAction = () => {
|
||||||
if(isOpen.value){
|
if (isOpen.value) {
|
||||||
collapseAll(menus.value);
|
collapseAll(menus.value)
|
||||||
isOpen.value = false;
|
isOpen.value = false
|
||||||
}else{
|
} else {
|
||||||
unFoldAll(menus.value);
|
unFoldAll(menus.value)
|
||||||
isOpen.value = true;
|
isOpen.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全部展开
|
// 全部展开
|
||||||
const unFoldAll = (data:any) => {
|
const unFoldAll = (data:any) => {
|
||||||
|
|
||||||
Object.keys(data).forEach((key:string|any) => {
|
Object.keys(data).forEach((key:string|any) => {
|
||||||
treeRef.value.store.nodesMap[data[key]['menu_key']].expanded = true;
|
treeRef.value.store.nodesMap[data[key].menu_key].expanded = true
|
||||||
if(data[key].children && data[key].children.length > 0) collapseAll(data[key].children);
|
if (data[key].children && data[key].children.length > 0) collapseAll(data[key].children)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 全部折叠
|
// 全部折叠
|
||||||
const collapseAll = (data:any) => {
|
const collapseAll = (data:any) => {
|
||||||
Object.keys(data).forEach((key:string|any) => {
|
Object.keys(data).forEach((key:string|any) => {
|
||||||
treeRef.value.store.nodesMap[data[key]['menu_key']].expanded = false;
|
treeRef.value.store.nodesMap[data[key].menu_key].expanded = false
|
||||||
if(data[key].children && data[key].children.length > 0) collapseAll(data[key].children);
|
if (data[key].children && data[key].children.length > 0) collapseAll(data[key].children)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -143,7 +141,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
const data = Object.assign({}, formData)
|
const data = Object.assign({}, formData)
|
||||||
data.rules = data.rules.concat(treeRef.value.getHalfCheckedKeys());
|
data.rules = data.rules.concat(treeRef.value.getHalfCheckedKeys())
|
||||||
|
|
||||||
save(data).then(res => {
|
save(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@ -167,42 +165,37 @@ const setFormData = async (row: any = null) => {
|
|||||||
popTitle = t('updateRole')
|
popTitle = t('updateRole')
|
||||||
const data = await (await getRoleInfo(row.role_id)).data
|
const data = await (await getRoleInfo(row.role_id)).data
|
||||||
Object.keys(formData).forEach((key: string) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
|
|
||||||
if (data[key] != undefined) {
|
if (data[key] != undefined) {
|
||||||
if(key == 'rules'){
|
if (key == 'rules') {
|
||||||
var arr = data.rules;
|
const arr = data.rules
|
||||||
var newArr:any = [];
|
const newArr:any = []
|
||||||
|
|
||||||
Object.keys(data.rules).forEach( (i) => {
|
Object.keys(data.rules).forEach((i) => {
|
||||||
checked(data.rules[i],menus.value,newArr)
|
checked(data.rules[i], menus.value, newArr)
|
||||||
} )
|
})
|
||||||
formData[key] = newArr;
|
formData[key] = newArr
|
||||||
|
} else {
|
||||||
}else{
|
|
||||||
formData[key] = data[key]
|
formData[key] = data[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checked (menuKey:string, data:any, newArr:any) {
|
||||||
function checked(menu_key:string,data:any,newArr:any) {
|
Object.keys(data).forEach((key:string) => {
|
||||||
Object.keys(data).forEach( (key:string) =>{
|
const item = data[key]
|
||||||
let item = data[key]
|
if (item.menu_key == menuKey) {
|
||||||
if(item.menu_key == menu_key){
|
if (!item.children || item.children.length == 0) {
|
||||||
if(!item.children || item.children.length == 0){
|
|
||||||
newArr.push(item.menu_key)
|
newArr.push(item.menu_key)
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if(item.children && item.children.length > 0){
|
if (item.children && item.children.length > 0) {
|
||||||
checked(menu_key,item.children,newArr)
|
checked(menuKey, item.children, newArr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} )
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@ -69,15 +69,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed, toRaw, watch } from 'vue'
|
import { ref, reactive, computed, toRaw } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { getUserInfo, getAllUserList } from '@/app/api/user'
|
import { getUserInfo, getAllUserList } from '@/app/api/user'
|
||||||
import { addUser, editUser } from '@/app/api/site'
|
import { addUser, editUser } from '@/app/api/site'
|
||||||
import { allRole } from '@/app/api/sys'
|
import { allRole } from '@/app/api/sys'
|
||||||
import { img, deepClone } from '@/utils/common'
|
import { img, deepClone } from '@/utils/common'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
|
||||||
const userList = ref([])
|
const userList = ref<AnyObject>([])
|
||||||
const uid = ref<number | string>('')
|
const uid = ref<number | string>('')
|
||||||
|
|
||||||
const selectUser = (value: any) => {
|
const selectUser = (value: any) => {
|
||||||
@ -165,7 +166,7 @@ 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 => {
|
roles.value.forEach((element:any) => {
|
||||||
element.role_id = element.role_id.toString()
|
element.role_id = element.role_id.toString()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<span v-html="`${menuLevel}${prop.menu.menu_name}`"></span>
|
<span v-html="`${menuLevel}${prop.menu.menu_name}`"></span>
|
||||||
</el-option>
|
</el-option>
|
||||||
<template v-if="prop.menu.children">
|
<template v-if="prop.menu.children">
|
||||||
<select-menu-item :menu="item" v-for="item in prop.menu.children" :level="prop.level + 1" />
|
<select-menu-item :menu="item" v-for="(item,index) in prop.menu.children" :level="prop.level + 1" :key="index" />
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop:any = defineProps({
|
||||||
menu: Object,
|
menu: Object,
|
||||||
level: {
|
level: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
|||||||
@ -21,26 +21,40 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
// import type { FormInstance } from 'element-plus'
|
||||||
import { getLogInfo } from '@/app/api/site'
|
import { getLogInfo } from '@/app/api/site'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
const logData = ref([])
|
interface LogData {
|
||||||
|
username: string
|
||||||
|
ip: string,
|
||||||
|
url: string,
|
||||||
|
type: string,
|
||||||
|
params:any
|
||||||
|
}
|
||||||
|
|
||||||
|
const logData = ref<LogData>({
|
||||||
|
username: '',
|
||||||
|
ip: '',
|
||||||
|
url: '',
|
||||||
|
type: '',
|
||||||
|
params: ''
|
||||||
|
})
|
||||||
const getLogDetail = async () => {
|
const getLogDetail = async () => {
|
||||||
logData.value = await (await getLogInfo(id)).data
|
logData.value = await (await getLogInfo(id)).data
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = 0;
|
let id = 0
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if (row) {
|
if (row) {
|
||||||
id = row.id;
|
id = row.id
|
||||||
getLogDetail();
|
getLogDetail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,30 +56,27 @@ import { reactive, ref } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getLogList } from '@/app/api/site'
|
import { getLogList } from '@/app/api/site'
|
||||||
import UserLogDetail from '@/app/views/auth/components/user-log-detail.vue'
|
import UserLogDetail from '@/app/views/auth/components/user-log-detail.vue'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import { FormInstance } from 'element-plus'
|
import { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
const route = useRoute()
|
const sysUserLogTableData = reactive({
|
||||||
const pageName = route.meta.title;
|
|
||||||
|
|
||||||
let sysUserLogTableData = reactive({
|
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
ip:"",
|
ip: '',
|
||||||
username:"",
|
username: '',
|
||||||
|
url: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadSysUserLogList();
|
loadSysUserLogList()
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取管理员操作记录表列表
|
* 获取管理员操作记录表列表
|
||||||
@ -91,7 +88,7 @@ const loadSysUserLogList = (page: number = 1) => {
|
|||||||
getLogList({
|
getLogList({
|
||||||
page: sysUserLogTableData.page,
|
page: sysUserLogTableData.page,
|
||||||
limit: sysUserLogTableData.limit,
|
limit: sysUserLogTableData.limit,
|
||||||
...sysUserLogTableData.searchParam
|
...sysUserLogTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
sysUserLogTableData.loading = false
|
sysUserLogTableData.loading = false
|
||||||
sysUserLogTableData.data = res.data.data
|
sysUserLogTableData.data = res.data.data
|
||||||
@ -106,7 +103,7 @@ const userLogDetailDialog: Record<string, any> | null = ref(null)
|
|||||||
* 查看详情
|
* 查看详情
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const detailEvent = (data: any) => {
|
const detailEvent = (data: any) => {
|
||||||
userLogDetailDialog.value.setFormData(data)
|
userLogDetailDialog.value.setFormData(data)
|
||||||
userLogDetailDialog.value.showDialog = true
|
userLogDetailDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
<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">
|
||||||
|
<div class="flex justify-between items-center mb-[20px]">
|
||||||
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
|
<el-button type="primary" class="w-[100px]" @click="addEvent">
|
||||||
|
{{ t('addMenu') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-table :data="menusTableData.data" row-key="menu_key" size="large" v-loading="menusTableData.loading">
|
<el-table :data="menusTableData.data" row-key="menu_key" size="large" v-loading="menusTableData.loading">
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !menusTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !menusTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
@ -22,19 +29,19 @@
|
|||||||
<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('statusNormal') }}</el-tag>
|
||||||
<el-tag class="ml-2" type="error" v-if="row.status == 0">{{t('statusDeactivate') }}</el-tag>
|
<el-tag class="ml-2" type="error" v-if="row.status == 0">{{ t('statusDeactivate') }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="sort" :label="t('sort')" min-width="100" />
|
<el-table-column prop="sort" :label="t('sort')" min-width="100" />
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="130">
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="130">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<!-- <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 type="primary" link @click="deleteEvent(row.menu_key)">{{ t('delete') }}</el-button> -->
|
<el-button type="primary" link @click="deleteEvent(row.menu_key)">{{ t('delete') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<edit-menu ref="editMenuDialog" :menu-tree="menusTableData.data" @complete="getMenuList" />
|
<edit-menu ref="editMenuDialog" :menu-tree="menusTableData.data" @complete="getMenuList" app-type="admin" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -45,11 +52,10 @@ import { getMenus, deleteMenu } from '@/app/api/sys'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
import EditMenu from '@/app/views/auth/components/edit-menu.vue'
|
import EditMenu from '@/app/views/auth/components/edit-menu.vue'
|
||||||
|
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
|
|
||||||
const menusTableData = reactive({
|
const menusTableData = reactive({
|
||||||
loading: true,
|
loading: true,
|
||||||
data: []
|
data: []
|
||||||
@ -91,7 +97,7 @@ const editEvent = (data: any) => {
|
|||||||
/**
|
/**
|
||||||
* 删除菜单
|
* 删除菜单
|
||||||
*/
|
*/
|
||||||
const deleteEvent = (menu_key: string) => {
|
const deleteEvent = (key: string) => {
|
||||||
ElMessageBox.confirm(t('menuDeleteTips'), t('warning'),
|
ElMessageBox.confirm(t('menuDeleteTips'), t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@ -99,7 +105,7 @@ const deleteEvent = (menu_key: string) => {
|
|||||||
type: 'warning'
|
type: 'warning'
|
||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
deleteMenu(menu_key).then(res => {
|
deleteMenu('admin', key).then(() => {
|
||||||
getMenuList()
|
getMenuList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
|
|||||||
@ -52,27 +52,23 @@ import { getRoleList, deleteRole } from '@/app/api/sys'
|
|||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import EditRole from '@/app/views/auth/components/edit-role.vue'
|
import EditRole from '@/app/views/auth/components/edit-role.vue'
|
||||||
|
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
const route = useRoute()
|
|
||||||
const pageName = route.meta.title;
|
|
||||||
|
|
||||||
const roleTableData = reactive({
|
const roleTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
seach:''
|
seach: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadRoleList();
|
loadRoleList()
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取角色列表
|
* 获取角色列表
|
||||||
|
|||||||
@ -1,39 +1,91 @@
|
|||||||
<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">
|
||||||
|
<div class="flex justify-between items-center mb-[20px]">
|
||||||
|
<span class="text-[20px]"></span>
|
||||||
|
<el-button type="primary" class="w-[100px]" @click="addEvent">
|
||||||
|
{{ t('addMenu') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-table :data="menusTableData.data" row-key="menu_key" size="large" v-loading="menusTableData.loading">
|
<el-tabs v-model="active">
|
||||||
<template #empty>
|
<el-tab-pane :label="t('system')" name="system">
|
||||||
<span>{{ !menusTableData.loading ? t('emptyData') : '' }}</span>
|
<el-table :data="menusTableData.system" row-key="menu_key" size="large"
|
||||||
</template>
|
v-loading="menusTableData.loading">
|
||||||
<el-table-column prop="menu_name" :show-overflow-tooltip="true" :label="t('menuName')" min-width="150" />
|
<template #empty>
|
||||||
<el-table-column :label="t('icon')" width="100" align="center">
|
<span>{{ !menusTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
<template #default="{ row }">
|
</template>
|
||||||
<icon v-if="row.icon" :name="row.icon" size="18px" />
|
<el-table-column prop="menu_name" :show-overflow-tooltip="true" :label="t('menuName')"
|
||||||
</template>
|
min-width="150" />
|
||||||
</el-table-column>
|
<el-table-column :label="t('icon')" width="100" align="center">
|
||||||
<el-table-column :label="t('menuType')" width="80">
|
<template #default="{ row }">
|
||||||
<template #default="{ row }">
|
<icon v-if="row.icon" :name="row.icon" size="18px" />
|
||||||
<div v-if="row.menu_type == 0">{{ t('menuTypeDir') }}</div>
|
</template>
|
||||||
<div v-else-if="row.menu_type == 1">{{ t('menuTypeMenu') }}</div>
|
</el-table-column>
|
||||||
<div v-else-if="row.menu_type == 2">{{ t('menuTypeButton') }}</div>
|
<el-table-column :label="t('menuType')" width="80">
|
||||||
</template>
|
<template #default="{ row }">
|
||||||
</el-table-column>
|
<div v-if="row.menu_type == 0">{{ t('menuTypeDir') }}</div>
|
||||||
<el-table-column prop="api_url" :label="t('authId')" min-width="150" align="center" />
|
<div v-else-if="row.menu_type == 1">{{ t('menuTypeMenu') }}</div>
|
||||||
<el-table-column :label="t('status')" min-width="120" align="center">
|
<div v-else-if="row.menu_type == 2">{{ t('menuTypeButton') }}</div>
|
||||||
<template #default="{ row }">
|
</template>
|
||||||
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ t('statusNormal') }}</el-tag>
|
</el-table-column>
|
||||||
<el-tag class="ml-2" type="error" v-if="row.status == 0">{{t('statusDeactivate') }}</el-tag>
|
<el-table-column prop="api_url" :label="t('authId')" min-width="150" align="center" />
|
||||||
</template>
|
<el-table-column :label="t('status')" min-width="120" align="center">
|
||||||
</el-table-column>
|
<template #default="{ row }">
|
||||||
<el-table-column prop="sort" :label="t('sort')" min-width="100" />
|
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ t('statusNormal') }}</el-tag>
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="130">
|
<el-tag class="ml-2" type="error" v-if="row.status == 0">{{ t('statusDeactivate')
|
||||||
<template #default="{ row }">
|
}}</el-tag>
|
||||||
<!-- <el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
</template>
|
||||||
<el-button type="primary" link @click="deleteEvent(row.menu_key)">{{ t('delete') }}</el-button> -->
|
</el-table-column>
|
||||||
</template>
|
<el-table-column prop="sort" :label="t('sort')" min-width="100" />
|
||||||
</el-table-column>
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="130">
|
||||||
</el-table>
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="deleteEvent(row.menu_key)">{{ t('delete')
|
||||||
|
}}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="t('application')" name="application">
|
||||||
|
<el-table :data="menusTableData.application" row-key="menu_key" size="large"
|
||||||
|
v-loading="menusTableData.loading">
|
||||||
|
<template #empty>
|
||||||
|
<span>{{ !menusTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
|
</template>
|
||||||
|
<el-table-column prop="menu_name" :show-overflow-tooltip="true" :label="t('menuName')"
|
||||||
|
min-width="150" />
|
||||||
|
<el-table-column :label="t('icon')" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<icon v-if="row.icon" :name="row.icon" size="18px" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="t('menuType')" width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="row.menu_type == 0">{{ t('menuTypeDir') }}</div>
|
||||||
|
<div v-else-if="row.menu_type == 1">{{ t('menuTypeMenu') }}</div>
|
||||||
|
<div v-else-if="row.menu_type == 2">{{ t('menuTypeButton') }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="api_url" :label="t('authId')" min-width="150" align="center" />
|
||||||
|
<el-table-column :label="t('status')" min-width="120" align="center">
|
||||||
|
<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="error" v-if="row.status == 0">{{ t('statusDeactivate')
|
||||||
|
}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="sort" :label="t('sort')" min-width="100" />
|
||||||
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="130">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="deleteEvent(row.menu_key)">{{ t('delete')
|
||||||
|
}}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
<edit-menu ref="editMenuDialog" :menu-tree="menusTableData.data" @complete="getMenuList" />
|
<edit-menu ref="editMenuDialog" :menu-tree="menusTableData.data" @complete="getMenuList" />
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -49,11 +101,12 @@ import EditMenu from '@/app/views/auth/components/edit-menu.vue'
|
|||||||
|
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const active = ref('system')
|
||||||
|
|
||||||
const menusTableData = reactive({
|
const menusTableData = reactive<Record<string, any>>({
|
||||||
loading: true,
|
loading: true,
|
||||||
data: []
|
system: [],
|
||||||
|
application: []
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,9 +114,15 @@ const menusTableData = reactive({
|
|||||||
*/
|
*/
|
||||||
const getMenuList = () => {
|
const getMenuList = () => {
|
||||||
menusTableData.loading = true
|
menusTableData.loading = true
|
||||||
getMenus('site').then(res => {
|
getMenus('site').then(({ data }) => {
|
||||||
menusTableData.loading = false
|
menusTableData.loading = false
|
||||||
menusTableData.data = res.data
|
const system: Record<string, any>[] = []
|
||||||
|
const application: Record<string, any> = []
|
||||||
|
data.forEach((item: any) => {
|
||||||
|
item.addon == '' ? system.push(item) : application.push(item)
|
||||||
|
})
|
||||||
|
menusTableData.system = system
|
||||||
|
menusTableData.application = application
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -92,7 +151,7 @@ const editEvent = (data: any) => {
|
|||||||
/**
|
/**
|
||||||
* 删除菜单
|
* 删除菜单
|
||||||
*/
|
*/
|
||||||
const deleteEvent = (menu_key: string) => {
|
const deleteEvent = (key: string) => {
|
||||||
ElMessageBox.confirm(t('menuDeleteTips'), t('warning'),
|
ElMessageBox.confirm(t('menuDeleteTips'), t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@ -100,7 +159,7 @@ const deleteEvent = (menu_key: string) => {
|
|||||||
type: 'warning'
|
type: 'warning'
|
||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
deleteMenu(menu_key).then(res => {
|
deleteMenu('site', key).then(res => {
|
||||||
getMenuList()
|
getMenuList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
|
|||||||
@ -97,7 +97,8 @@ const userTableData = reactive({
|
|||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam: {
|
searchParam: {
|
||||||
seach: ''
|
seach: '',
|
||||||
|
user_type: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -77,7 +77,6 @@
|
|||||||
<p class="text-[#999] text-[12px]">{{ t('aliappSet') }}</p>
|
<p class="text-[#999] text-[12px]">{{ t('aliappSet') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="w-full p-5 bg-white">
|
<div class="w-full p-5 bg-white">
|
||||||
@ -219,10 +218,10 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<el-image class="w-[180px] h-[180px]" :src="qr_code ? img(qr_code) : ''">
|
<el-image class="w-[180px] h-[180px]" :src="qrCode ? img(qrCode) : ''">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="w-[100%] h-[100%] flex items-center justify-center bg-[#f5f7fa]">
|
<div class="w-[100%] h-[100%] flex items-center justify-center bg-[#f5f7fa]">
|
||||||
<span>{{ qr_code ? t('fileErr') : t('emptyQrCode') }}</span>
|
<span>{{ qrCode ? t('fileErr') : t('emptyQrCode') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
@ -236,26 +235,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getAliappConfig } from '@/app/api/aliapp'
|
import { getAliappConfig } from '@/app/api/aliapp'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
let activeName = ref("/channel/aliapp");
|
const activeName = ref('/channel/aliapp')
|
||||||
let active = ref(2);
|
const active = ref(2)
|
||||||
let qr_code = ref('')
|
const qrCode = ref<string>('')
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
let res = await getAliappConfig()
|
const res = await getAliappConfig()
|
||||||
qr_code.value = res.data.qr_code
|
qrCode.value = res.data.qr_code
|
||||||
})
|
})
|
||||||
const linkEvent = (url: string) => {
|
const linkEvent = (url: string) => {
|
||||||
window.open(url, "_blank")
|
window.open(url, '_blank')
|
||||||
}
|
}
|
||||||
const handleClick = (val: any) => {
|
const handleClick = (val: any) => {
|
||||||
router.push({ path: activeName.value });
|
router.push({ path: activeName.value })
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -310,4 +309,5 @@ const handleClick = (val: any) => {
|
|||||||
:deep(.el-step__title) {
|
:deep(.el-step__title) {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
line-height: 40px !important;
|
line-height: 40px !important;
|
||||||
}</style>
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -100,10 +100,10 @@
|
|||||||
</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 { getWechatConfig } from '@/app/api/wechat'
|
import { getWechatConfig } from '@/app/api/wechat'
|
||||||
import { img } from '@/utils/common'
|
// import { img } from '@/utils/common'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -111,26 +111,26 @@ const router = useRouter()
|
|||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const formData = reactive<Record<string, string>>({
|
const formData = reactive<Record<string, string>>({
|
||||||
wechat_name: '',
|
wechat_name: '',
|
||||||
wechat_original: '',
|
wechat_original: '',
|
||||||
app_id: '',
|
app_id: '',
|
||||||
app_secret: '',
|
app_secret: '',
|
||||||
qr_code: '',
|
qr_code: '',
|
||||||
token: '',
|
token: '',
|
||||||
encoding_aes_key: '',
|
encoding_aes_key: '',
|
||||||
encryption_type: 'not_encrypt'
|
encryption_type: 'not_encrypt'
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取微信配置
|
* 获取微信配置
|
||||||
*/
|
*/
|
||||||
getWechatConfig().then(res => {
|
getWechatConfig().then(res => {
|
||||||
Object.assign(formData, res.data)
|
Object.assign(formData, res.data)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const linkEvent = () => {
|
const linkEvent = () => {
|
||||||
window.open("https://open.alipay.com/develop/manage", "_blank")
|
window.open('https://open.alipay.com/develop/manage', '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -42,7 +42,7 @@ const pageName = route.meta.title
|
|||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
const formData = reactive<Record<string, string | boolean>>({
|
const formData = reactive<Record<string, string | boolean | any>>({
|
||||||
is_open: false,
|
is_open: false,
|
||||||
request_url: ''
|
request_url: ''
|
||||||
})
|
})
|
||||||
@ -54,13 +54,13 @@ const formRef = ref<FormInstance>()
|
|||||||
*/
|
*/
|
||||||
getH5Config().then(res => {
|
getH5Config().then(res => {
|
||||||
Object.assign(formData, res.data)
|
Object.assign(formData, res.data)
|
||||||
formData.is_open = Boolean(Number(formData.is_open));
|
formData.is_open = Boolean(Number(formData.is_open))
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
* 获取h5域名
|
* 获取h5域名
|
||||||
*/
|
*/
|
||||||
getUrl().then(res => {
|
getUrl().then(res => {
|
||||||
formData.request_url = res.data.wap_url + '/'
|
formData.request_url = res.data.wap_url + '/'
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ watch(copied, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 点击访问
|
// 点击访问
|
||||||
const visitFn = ()=>{
|
const visitFn = () => {
|
||||||
window.open(formData.request_url);
|
window.open(formData.request_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,8 +102,8 @@ 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
|
||||||
let data = {...formData};
|
const data = { ...formData }
|
||||||
data.is_open = Number(data.is_open);
|
data.is_open = Number(data.is_open)
|
||||||
setH5Config(data).then(() => {
|
setH5Config(data).then(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{pageName}}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-form :model="formData" label-width="150px" ref="formRef" class="page-form">
|
<el-form :model="formData" label-width="150px" ref="formRef" class="page-form">
|
||||||
|
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-form-item :label="t('preview')" prop="weapp_name">
|
<el-form-item :label="t('preview')" prop="weapp_name">
|
||||||
<img class="w-[500px]" src="@/app/assets/images/channel/preview.png" alt="">
|
<img class="w-[500px]" src="@/app/assets/images/channel/preview.png" alt="">
|
||||||
@ -30,26 +29,25 @@ import { t } from '@/lang'
|
|||||||
import { getUrl } from '@/app/api/sys'
|
import { getUrl } from '@/app/api/sys'
|
||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { ElMessage, FormInstance } from 'element-plus'
|
import { ElMessage, FormInstance } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
const formData = reactive<Record<string, string | boolean>>({
|
const formData = reactive<Record<string, string | boolean | any>>({
|
||||||
is_open: false,
|
is_open: false,
|
||||||
request_url: ''
|
request_url: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取pc域名
|
* 获取pc域名
|
||||||
*/
|
*/
|
||||||
getUrl().then(res => {
|
getUrl().then(res => {
|
||||||
formData.request_url = res.data.web_url + '/';
|
formData.request_url = res.data.web_url + '/'
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,8 +75,8 @@ watch(copied, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 点击访问
|
// 点击访问
|
||||||
const visitFn = ()=>{
|
const visitFn = () => {
|
||||||
window.open(formData.request_url);
|
window.open(formData.request_url)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -137,10 +137,10 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<el-image class="w-[180px] h-[180px]" :src="qr_code ? img(qr_code) : ''">
|
<el-image class="w-[180px] h-[180px]" :src="qrCode ? img(qrCode) : ''">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="w-[100%] h-[100%] flex items-center justify-center bg-[#f5f7fa]">
|
<div class="w-[100%] h-[100%] flex items-center justify-center bg-[#f5f7fa]">
|
||||||
<span>{{ qr_code ? t('fileErr') : t('emptyQrCode') }}</span>
|
<span>{{ qrCode ? t('fileErr') : t('emptyQrCode') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
@ -155,26 +155,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from 'vue'
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from 'vue-router'
|
||||||
import { t } from "@/lang";
|
import { t } from '@/lang'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getWeappConfig } from '@/app/api/weapp'
|
import { getWeappConfig } from '@/app/api/weapp'
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
let activeName = ref("/channel/weapp");
|
const activeName = ref('/channel/weapp')
|
||||||
let active = ref(2);
|
const active = ref(2)
|
||||||
let qr_code = ref('')
|
const qrCode = ref('')
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
let res = await getWeappConfig()
|
const res = await getWeappConfig()
|
||||||
qr_code.value = res.data.qr_code
|
qrCode.value = res.data.qr_code
|
||||||
})
|
})
|
||||||
const linkEvent = (url: string) => {
|
const linkEvent = (url: string) => {
|
||||||
window.open(url, "_blank");
|
window.open(url, '_blank')
|
||||||
};
|
}
|
||||||
const handleClick = (val: any) => {
|
const handleClick = (val: any) => {
|
||||||
router.push({ path: activeName.value });
|
router.push({ path: activeName.value })
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-dialog v-model="dialogVisible" :title="t('codeDownTwoDesc')" width="30%" :before-close="handleClose">
|
<el-dialog v-model="dialogVisible" :title="t('codeDownTwoDesc')" width="30%" :before-close="handleClose">
|
||||||
<el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="120px">
|
<el-form ref="ruleFormRef" :model="form" label-width="120px">
|
||||||
<el-form-item prop="code" :label="t('code')">
|
<el-form-item prop="code" :label="t('code')">
|
||||||
<el-input v-model="form.code" :placeholder="t('codePlaceholder')"
|
<el-input v-model="form.code" :placeholder="t('codePlaceholder')"
|
||||||
onkeyup="this.value = this.value.replace(/[^\d\.]/g,'');" />
|
onkeyup="this.value = this.value.replace(/[^\d\.]/g,'');" />
|
||||||
@ -76,13 +76,20 @@ import { t } from '@/lang'
|
|||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { getAuthinfo } from '@/app/api/module'
|
import { getAuthinfo } from '@/app/api/module'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
const activeNames = ref('1')
|
// const activeNames = ref('1')
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const weappTableData = reactive({
|
const weappTableData:{
|
||||||
|
page: number,
|
||||||
|
limit: number,
|
||||||
|
total: number,
|
||||||
|
loading: boolean,
|
||||||
|
data: AnyObject
|
||||||
|
} = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
@ -90,7 +97,10 @@ const weappTableData = reactive({
|
|||||||
data: []
|
data: []
|
||||||
})
|
})
|
||||||
const form = ref({
|
const form = ref({
|
||||||
desc: ''
|
desc: '',
|
||||||
|
code: '',
|
||||||
|
path: '',
|
||||||
|
content: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const authCode = ref('')
|
const authCode = ref('')
|
||||||
@ -102,7 +112,13 @@ getAuthinfo().then(res => {
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const weappConfig = ref({})
|
const weappConfig = ref<{
|
||||||
|
app_id:string,
|
||||||
|
app_secret:string
|
||||||
|
}>({
|
||||||
|
app_id: '',
|
||||||
|
app_secret: ''
|
||||||
|
})
|
||||||
getWeappConfig().then(res => {
|
getWeappConfig().then(res => {
|
||||||
weappConfig.value = res.data
|
weappConfig.value = res.data
|
||||||
})
|
})
|
||||||
@ -111,7 +127,7 @@ const activeName = ref('/channel/weapp/code')
|
|||||||
const handleClick = (val: any) => {
|
const handleClick = (val: any) => {
|
||||||
router.push({ path: activeName.value })
|
router.push({ path: activeName.value })
|
||||||
}
|
}
|
||||||
const ruleFormRef = ref(null)
|
const ruleFormRef = ref<any>(null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取版本列表
|
* 获取版本列表
|
||||||
|
|||||||
@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { img } from '@/utils/common'
|
// import { img } from '@/utils/common'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -76,7 +76,7 @@ const router = useRouter()
|
|||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
|
|
||||||
const linkEvent = () => {
|
const linkEvent = () => {
|
||||||
window.open("https://mp.weixin.qq.com/", "_blank")
|
window.open('https://mp.weixin.qq.com/', '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -68,14 +68,15 @@ import { getTemplateList, getBatchAcquisition } from '@/app/api/weapp'
|
|||||||
import { editNoticeStatus } from '@/app/api/notice'
|
import { editNoticeStatus } from '@/app/api/notice'
|
||||||
import { ElLoading } from 'element-plus'
|
import { ElLoading } from 'element-plus'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
let activeName = ref("/channel/weapp/message");
|
const activeName = ref('/channel/weapp/message')
|
||||||
const handleClick = (val: any) => {
|
const handleClick = (val: any) => {
|
||||||
router.push({ path: activeName.value });
|
router.push({ path: activeName.value })
|
||||||
};
|
}
|
||||||
const cronTableData = reactive({
|
const cronTableData = reactive({
|
||||||
loading: true,
|
loading: true,
|
||||||
data: []
|
data: []
|
||||||
@ -117,7 +118,7 @@ interface Switch {
|
|||||||
type: string;
|
type: string;
|
||||||
status: number
|
status: number
|
||||||
}
|
}
|
||||||
const infoSwitch = (res) => {
|
const infoSwitch = (res:any) => {
|
||||||
const data = ref<Switch>({
|
const data = ref<Switch>({
|
||||||
key: '',
|
key: '',
|
||||||
type: '',
|
type: '',
|
||||||
|
|||||||
@ -56,13 +56,13 @@ const prop = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRef = ref(null)
|
const formRef = ref()
|
||||||
|
|
||||||
const buttonData = computed({
|
const buttonData = computed({
|
||||||
get() {
|
get () {
|
||||||
return prop.data
|
return prop.data
|
||||||
},
|
},
|
||||||
set(value) {
|
set (value) {
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -60,10 +60,9 @@
|
|||||||
</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 { getWechatConfig } from '@/app/api/wechat'
|
import { getWechatConfig } from '@/app/api/wechat'
|
||||||
import { img } from '@/utils/common'
|
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -71,26 +70,26 @@ const pageName = route.meta.title
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const formData = reactive<Record<string, string>>({
|
const formData = reactive<Record<string, string>>({
|
||||||
wechat_name: '',
|
wechat_name: '',
|
||||||
wechat_original: '',
|
wechat_original: '',
|
||||||
app_id: '',
|
app_id: '',
|
||||||
app_secret: '',
|
app_secret: '',
|
||||||
qr_code: '',
|
qr_code: '',
|
||||||
token: '',
|
token: '',
|
||||||
encoding_aes_key: '',
|
encoding_aes_key: '',
|
||||||
encryption_type: 'not_encrypt'
|
encryption_type: 'not_encrypt'
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取微信配置
|
* 获取微信配置
|
||||||
*/
|
*/
|
||||||
getWechatConfig().then(res => {
|
getWechatConfig().then(res => {
|
||||||
Object.assign(formData, res.data)
|
Object.assign(formData, res.data)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const linkEvent = () => {
|
const linkEvent = () => {
|
||||||
window.open('https://mp.weixin.qq.com/', '_blank')
|
window.open('https://mp.weixin.qq.com/', '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -99,16 +99,16 @@ const button = ref<Record<string, any>[]>([])
|
|||||||
const buttonIndex = ref<number>(0)
|
const buttonIndex = ref<number>(0)
|
||||||
const subButtonIndex = ref<number>(-1)
|
const subButtonIndex = ref<number>(-1)
|
||||||
const formRef = ref<Record<string, any>[] | null>(null)
|
const formRef = ref<Record<string, any>[] | null>(null)
|
||||||
let activeName = ref("/channel/wechat/menu");
|
const activeName = ref('/channel/wechat/menu')
|
||||||
const handleClick = (val: any) => {
|
const handleClick = (val: any) => {
|
||||||
router.push({ path: activeName.value });
|
router.push({ path: activeName.value })
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* 获取公众号菜单配置
|
* 获取公众号菜单配置
|
||||||
*/
|
*/
|
||||||
getWechatMenu().then((res) => {
|
getWechatMenu().then((res) => {
|
||||||
button.value = res.data
|
button.value = res.data
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
<template></template>
|
<template>
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -84,15 +84,15 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
const cronTableData = reactive({
|
const cronTableData = reactive({
|
||||||
loading: true,
|
loading: true,
|
||||||
data: []
|
data: []
|
||||||
})
|
})
|
||||||
let activeName = ref("/channel/wechat/message");
|
const activeName = ref('/channel/wechat/message')
|
||||||
const handleClick = (val: any) => {
|
const handleClick = (val: any) => {
|
||||||
router.push({ path: activeName.value });
|
router.push({ path: activeName.value })
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* 获取消息模板列表
|
* 获取消息模板列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -64,13 +64,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { setDictData, getDictInfo } from '@/app/api/dict'
|
import { setDictData, getDictInfo } from '@/app/api/dict'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
let showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ const initialFormData = {
|
|||||||
name: '',
|
name: '',
|
||||||
value: '',
|
value: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
memo:'',
|
memo: ''
|
||||||
}
|
}
|
||||||
const formData = ref({ ...initialFormData })
|
const formData = ref({ ...initialFormData })
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
@ -99,7 +99,7 @@ const formRules = computed(() => {
|
|||||||
value: [
|
value: [
|
||||||
{ required: true, message: t('dataValuePlaceholder'), trigger: 'blur' }
|
{ required: true, message: t('dataValuePlaceholder'), trigger: 'blur' }
|
||||||
|
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const addEvent = () => {
|
const addEvent = () => {
|
||||||
@ -112,7 +112,7 @@ const editEvent = (row: any, index: number) => {
|
|||||||
type.value = 'edit'
|
type.value = 'edit'
|
||||||
tabelIndex.value = index
|
tabelIndex.value = index
|
||||||
formData.value = cloneDeep(initialFormData)
|
formData.value = cloneDeep(initialFormData)
|
||||||
formData.value = Object.assign(formData.value,cloneDeep( row))
|
formData.value = Object.assign(formData.value, cloneDeep(row))
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -126,9 +126,8 @@ const submit = async (formEl: FormInstance | undefined) => {
|
|||||||
tableDate.value.push(cloneDeep(formData.value))
|
tableDate.value.push(cloneDeep(formData.value))
|
||||||
} else {
|
} else {
|
||||||
tableDate.value.splice(tabelIndex.value, 1, cloneDeep(formData.value))
|
tableDate.value.splice(tabelIndex.value, 1, cloneDeep(formData.value))
|
||||||
|
|
||||||
}
|
}
|
||||||
tableDate.value.sort(function(a,b){return b.sort-a.sort})
|
tableDate.value.sort(function (a, b) { return b.sort - a.sort })
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -162,12 +161,10 @@ const setFormData = async (row: any = null) => {
|
|||||||
id.value = row.id
|
id.value = row.id
|
||||||
name.value = row.name
|
name.value = row.name
|
||||||
const data = await (await getDictInfo(row.id)).data
|
const data = await (await getDictInfo(row.id)).data
|
||||||
tableDate.value = data.dictionary
|
tableDate.value = data.dictionary
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
showDialog,
|
showDialog,
|
||||||
setFormData
|
setFormData
|
||||||
|
|||||||
@ -31,7 +31,7 @@ import { t } from '@/lang'
|
|||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { addDict, editDict, getDictInfo } from '@/app/api/dict'
|
import { addDict, editDict, getDictInfo } from '@/app/api/dict'
|
||||||
|
|
||||||
let showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +41,7 @@ const initialFormData = {
|
|||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
key: '',
|
key: '',
|
||||||
memo: '',
|
memo: ''
|
||||||
|
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
@ -52,13 +52,13 @@ const formRef = ref<FormInstance>()
|
|||||||
const formRules = computed(() => {
|
const formRules = computed(() => {
|
||||||
return {
|
return {
|
||||||
name: [
|
name: [
|
||||||
{required: true, message: t('namePlaceholder'), trigger: 'blur'}
|
{ required: true, message: t('namePlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
key: [
|
key: [
|
||||||
{required: true, message: t('keyPlaceholder'), trigger: 'blur'}
|
{ required: true, message: t('keyPlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
data: [
|
data: [
|
||||||
{required: true, message: t('dataPlaceholder'), trigger: 'blur'}
|
{ required: true, message: t('dataPlaceholder'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -71,19 +71,19 @@ 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.id ? editDict : addDict
|
const save = formData.id ? editDict : addDict
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
let data = formData
|
const data = formData
|
||||||
|
|
||||||
save(data).then(res => {
|
save(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -93,11 +93,13 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if(row){
|
if (row) {
|
||||||
const data = await (await getDictInfo(row.id)).data
|
const data = await (await getDictInfo(row.id)).data
|
||||||
if (data) Object.keys(formData).forEach((key: string) => {
|
if (data) {
|
||||||
if (data[key] != undefined) formData[key] = data[key]
|
Object.keys(formData).forEach((key: string) => {
|
||||||
})
|
if (data[key] != undefined) formData[key] = data[key]
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,27 +57,27 @@
|
|||||||
</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 { getDictList, deleteDict } from '@/app/api/dict'
|
import { getDictList, deleteDict } from '@/app/api/dict'
|
||||||
import { img } from '@/utils/common'
|
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
import Edit from '@/app/views/dict/components/edit.vue'
|
import Edit from '@/app/views/dict/components/edit.vue'
|
||||||
import dict from '@/app/views/dict/components/dict.vue'
|
import dict from '@/app/views/dict/components/dict.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let dictTable = reactive({
|
const dictTable = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
"name":"",
|
name: '',
|
||||||
"key":""
|
key: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ const loadDictList = (page: number = 1) => {
|
|||||||
getDictList({
|
getDictList({
|
||||||
page: dictTable.page,
|
page: dictTable.page,
|
||||||
limit: dictTable.limit,
|
limit: dictTable.limit,
|
||||||
...dictTable.searchParam
|
...dictTable.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
dictTable.loading = false
|
dictTable.loading = false
|
||||||
dictTable.data = res.data.data
|
dictTable.data = res.data.data
|
||||||
@ -137,7 +137,7 @@ const deleteEvent = (id: number) => {
|
|||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
cancelButtonText: t('cancel'),
|
cancelButtonText: t('cancel'),
|
||||||
type: 'warning',
|
type: 'warning'
|
||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
deleteDict(id).then(() => {
|
deleteDict(id).then(() => {
|
||||||
@ -147,14 +147,12 @@ const deleteEvent = (id: number) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields()
|
formEl.resetFields()
|
||||||
loadDictList()
|
loadDictList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -60,105 +60,103 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import {ref, reactive,onMounted, nextTick} from 'vue'
|
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||||
import {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getWapIndexList } from '@/app/api/sys'
|
import { getWapIndexList } from '@/app/api/sys'
|
||||||
import Sortable from 'sortablejs'
|
import Sortable from 'sortablejs'
|
||||||
import {range} from 'lodash-es'
|
import { range } from 'lodash-es'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
// 组件验证
|
// 组件验证
|
||||||
diyStore.editComponent.verify = (index: number) => {
|
diyStore.editComponent.verify = (index: number) => {
|
||||||
var res = {code: true, message: ''};
|
const res = { code: true, message: '' }
|
||||||
// if (diyStore.value[index].list.length === 0) {
|
// if (diyStore.value[index].list.length === 0) {
|
||||||
// res.code = false;
|
// res.code = false;
|
||||||
// res.message = t('selectAddonTips');
|
// res.message = t('selectAddonTips');
|
||||||
// }
|
// }
|
||||||
return res;
|
return res
|
||||||
};
|
}
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
|
|
||||||
const addonBoxRef = ref()
|
const addonBoxRef = ref()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const sortable = Sortable.create(addonBoxRef.value, {
|
const sortable = Sortable.create(addonBoxRef.value, {
|
||||||
group: 'item-wrap',
|
group: 'item-wrap',
|
||||||
animation: 200,
|
animation: 200,
|
||||||
onEnd: event => {
|
onEnd: event => {
|
||||||
const temp = diyStore.editComponent.list[event.oldIndex!];
|
const temp = diyStore.editComponent.list[event.oldIndex!]
|
||||||
diyStore.editComponent.list.splice(event.oldIndex!, 1);
|
diyStore.editComponent.list.splice(event.oldIndex!, 1)
|
||||||
diyStore.editComponent.list.splice(event.newIndex!, 0, temp);
|
diyStore.editComponent.list.splice(event.newIndex!, 0, temp)
|
||||||
sortable.sort(
|
sortable.sort(
|
||||||
range(diyStore.editComponent.list.length).map(value => {
|
range(diyStore.editComponent.list.length).map(value => {
|
||||||
return value.toString();
|
return value.toString()
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
const addonTableData = reactive({
|
|
||||||
page: 1,
|
|
||||||
limit: 10,
|
|
||||||
total: 0,
|
|
||||||
loading: true,
|
|
||||||
data: [],
|
|
||||||
searchParam: {
|
|
||||||
title: '',
|
|
||||||
key: '',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取插件列表
|
|
||||||
const loadAddonList = (page: number = 1) => {
|
|
||||||
addonTableData.loading = true
|
|
||||||
addonTableData.page = page
|
|
||||||
|
|
||||||
getWapIndexList({
|
|
||||||
...addonTableData.searchParam
|
|
||||||
}).then(res => {
|
|
||||||
addonTableData.loading = false
|
|
||||||
addonTableData.data = res.data
|
|
||||||
addonTableData.total = res.data.length
|
|
||||||
}).catch(() => {
|
|
||||||
addonTableData.loading = false
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const addonTableData = reactive({
|
||||||
|
page: 1,
|
||||||
|
limit: 10,
|
||||||
|
total: 0,
|
||||||
|
loading: true,
|
||||||
|
data: [],
|
||||||
|
searchParam: {
|
||||||
|
title: '',
|
||||||
|
key: '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取插件列表
|
||||||
|
const loadAddonList = (page: number = 1) => {
|
||||||
|
addonTableData.loading = true
|
||||||
|
addonTableData.page = page
|
||||||
|
|
||||||
|
getWapIndexList({
|
||||||
|
...addonTableData.searchParam
|
||||||
|
}).then(res => {
|
||||||
|
addonTableData.loading = false
|
||||||
|
addonTableData.data = res.data
|
||||||
|
addonTableData.total = res.data.length
|
||||||
|
}).catch(() => {
|
||||||
|
addonTableData.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAddonList()
|
||||||
|
|
||||||
|
const handleCurrentChange = (val:any) => {
|
||||||
|
const item:any = {
|
||||||
|
id: diyStore.generateRandom(),
|
||||||
|
key: '',
|
||||||
|
title: '',
|
||||||
|
url: '',
|
||||||
|
icon: '',
|
||||||
|
desc: ''
|
||||||
|
}
|
||||||
|
for (let k in val) {
|
||||||
|
item[k] = val[k]
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAddonList()
|
diyStore.editComponent.list.push(item)
|
||||||
|
showDialog.value = false
|
||||||
|
}
|
||||||
|
|
||||||
const handleCurrentChange = (val) => {
|
const addAddon = () => {
|
||||||
let item:any = {
|
showDialog.value = true
|
||||||
id: diyStore.generateRandom(),
|
}
|
||||||
key: '',
|
|
||||||
title: '',
|
|
||||||
url: '',
|
|
||||||
icon: '',
|
|
||||||
desc: ''
|
|
||||||
};
|
|
||||||
for (let k in val) {
|
|
||||||
item[k] = val[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
diyStore.editComponent.list.push(item)
|
defineExpose({})
|
||||||
showDialog.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const addAddon = () => {
|
|
||||||
showDialog.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
</style>
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
</style>
|
</style>
|
||||||
@ -135,96 +135,96 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, watch, onMounted, nextTick} from 'vue'
|
import { ref, watch, onMounted, nextTick } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import Sortable from 'sortablejs'
|
import Sortable from 'sortablejs'
|
||||||
import {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import {range} from 'lodash-es'
|
import { range } from 'lodash-es'
|
||||||
|
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
// 组件验证
|
// 组件验证
|
||||||
diyStore.editComponent.verify = (index: number) => {
|
diyStore.editComponent.verify = (index: number) => {
|
||||||
var res = {code: true, message: ''};
|
const res = { code: true, message: '' }
|
||||||
|
|
||||||
diyStore.value[index].list.forEach((item: any) => {
|
diyStore.value[index].list.forEach((item: any) => {
|
||||||
if ((diyStore.value[index].mode === 'graphic' || diyStore.value[index].mode === 'img') && item.imageUrl === '') {
|
if ((diyStore.value[index].mode === 'graphic' || diyStore.value[index].mode === 'img') && item.imageUrl === '') {
|
||||||
res.code = false;
|
res.code = false
|
||||||
res.message = t('imageUrlTip');
|
res.message = t('imageUrlTip')
|
||||||
return res;
|
return res
|
||||||
}
|
}
|
||||||
if ((diyStore.value[index].mode === 'graphic' || diyStore.value[index].mode === 'text') && item.title === '') {
|
if ((diyStore.value[index].mode === 'graphic' || diyStore.value[index].mode === 'text') && item.title === '') {
|
||||||
res.code = false;
|
res.code = false
|
||||||
res.message = t('graphicNavTitlePlaceholder');
|
res.message = t('graphicNavTitlePlaceholder')
|
||||||
return res;
|
return res
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
diyStore.editComponent.list.forEach((item: any) => {
|
|
||||||
if (!item.id) item.id = diyStore.generateRandom();
|
|
||||||
})
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
diyStore.editComponent.list.forEach((item: any) => {
|
||||||
() => diyStore.editComponent.list,
|
if (!item.id) item.id = diyStore.generateRandom()
|
||||||
(newValue, oldValue) => {
|
})
|
||||||
// 设置图片宽高
|
|
||||||
diyStore.editComponent.list.forEach((item: any) => {
|
|
||||||
let image = new Image();
|
|
||||||
image.src = img(item.imageUrl);
|
|
||||||
image.onload = async () => {
|
|
||||||
item.imgWidth = image.width;
|
|
||||||
item.imgHeight = image.height;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{deep: true}
|
|
||||||
)
|
|
||||||
|
|
||||||
const addGraphicNav = () => {
|
watch(
|
||||||
diyStore.editComponent.list.push({
|
() => diyStore.editComponent.list,
|
||||||
id: diyStore.generateRandom(),
|
(newValue, oldValue) => {
|
||||||
title: '',
|
// 设置图片宽高
|
||||||
imageUrl: '',
|
diyStore.editComponent.list.forEach((item: any) => {
|
||||||
imgWidth: 0,
|
const image = new Image()
|
||||||
imgHeight: 0,
|
image.src = img(item.imageUrl)
|
||||||
link: {name: ''},
|
image.onload = async () => {
|
||||||
label: {
|
item.imgWidth = image.width
|
||||||
control: false,
|
item.imgHeight = image.height
|
||||||
text: '热门',
|
|
||||||
textColor: '#FFFFFF',
|
|
||||||
bgColorStart: '#F83287',
|
|
||||||
bgColorEnd: '#FE3423'
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
const imageBoxRef = ref()
|
const addGraphicNav = () => {
|
||||||
|
diyStore.editComponent.list.push({
|
||||||
onMounted(() => {
|
id: diyStore.generateRandom(),
|
||||||
nextTick(() => {
|
title: '',
|
||||||
const sortable = Sortable.create(imageBoxRef.value, {
|
imageUrl: '',
|
||||||
group: 'item-wrap',
|
imgWidth: 0,
|
||||||
animation: 200,
|
imgHeight: 0,
|
||||||
onEnd: event => {
|
link: { name: '' },
|
||||||
const temp = diyStore.editComponent.list[event.oldIndex!];
|
label: {
|
||||||
diyStore.editComponent.list.splice(event.oldIndex!, 1);
|
control: false,
|
||||||
diyStore.editComponent.list.splice(event.newIndex!, 0, temp);
|
text: '热门',
|
||||||
sortable.sort(
|
textColor: '#FFFFFF',
|
||||||
range(diyStore.editComponent.list.length).map(value => {
|
bgColorStart: '#F83287',
|
||||||
return value.toString();
|
bgColorEnd: '#FE3423'
|
||||||
})
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({})
|
const imageBoxRef = ref()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
const sortable = Sortable.create(imageBoxRef.value, {
|
||||||
|
group: 'item-wrap',
|
||||||
|
animation: 200,
|
||||||
|
onEnd: event => {
|
||||||
|
const temp = diyStore.editComponent.list[event.oldIndex!]
|
||||||
|
diyStore.editComponent.list.splice(event.oldIndex!, 1)
|
||||||
|
diyStore.editComponent.list.splice(event.newIndex!, 0, temp)
|
||||||
|
sortable.sort(
|
||||||
|
range(diyStore.editComponent.list.length).map(value => {
|
||||||
|
return value.toString()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -21,13 +21,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = ['pageBgColor','topRounded','bottomRounded','marginTop','marginBottom','marginBoth']; // 忽略公共属性
|
diyStore.editComponent.ignore = ['pageBgColor', 'topRounded', 'bottomRounded', 'marginTop', 'marginBottom', 'marginBoth'] // 忽略公共属性
|
||||||
|
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -33,39 +33,39 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
// 组件验证
|
// 组件验证
|
||||||
diyStore.editComponent.verify = (index: number) => {
|
diyStore.editComponent.verify = (index: number) => {
|
||||||
var res = {code: true, message: ''};
|
const res = { code: true, message: '' }
|
||||||
if (diyStore.value[index].imageUrl === '') {
|
if (diyStore.value[index].imageUrl === '') {
|
||||||
res.code = false;
|
res.code = false
|
||||||
res.message = t('imageUrlTip');
|
res.message = t('imageUrlTip')
|
||||||
return res;
|
return res
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectImg = (url: string) => {
|
|
||||||
handleHeight();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理高度
|
|
||||||
const handleHeight = () => {
|
|
||||||
let image = new Image();
|
|
||||||
image.src = img(diyStore.editComponent.imageUrl);
|
|
||||||
image.onload = async () => {
|
|
||||||
diyStore.editComponent.imgWidth = image.width;
|
|
||||||
diyStore.editComponent.imgHeight = image.height;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({})
|
const selectImg = (url: string) => {
|
||||||
|
handleHeight()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理高度
|
||||||
|
const handleHeight = () => {
|
||||||
|
const image = new Image()
|
||||||
|
image.src = img(diyStore.editComponent.imageUrl)
|
||||||
|
image.onload = async () => {
|
||||||
|
diyStore.editComponent.imgWidth = image.width
|
||||||
|
diyStore.editComponent.imgHeight = image.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -44,112 +44,112 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, watch, onMounted, nextTick} from 'vue'
|
import { ref, watch, onMounted, nextTick } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import Sortable from 'sortablejs'
|
import Sortable from 'sortablejs'
|
||||||
import {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import {range} from 'lodash-es'
|
import { range } from 'lodash-es'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
// 组件验证
|
// 组件验证
|
||||||
diyStore.editComponent.verify = (index: number) => {
|
diyStore.editComponent.verify = (index: number) => {
|
||||||
var res = {code: true, message: ''};
|
const res = { code: true, message: '' }
|
||||||
if(diyStore.value[index].imageHeight == 0){
|
if (diyStore.value[index].imageHeight == 0) {
|
||||||
res.code = false;
|
res.code = false
|
||||||
res.message = t('imageHeightPlaceholder');
|
res.message = t('imageHeightPlaceholder')
|
||||||
return res;
|
return res
|
||||||
|
}
|
||||||
|
if (!/^\d+.?\d{0,2}$/.test(diyStore.value[index].imageHeight)) {
|
||||||
|
res.code = false
|
||||||
|
res.message = t('imageHeightRegNum')
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
diyStore.value[index].list.forEach((item: any) => {
|
||||||
|
if (item.imageUrl === '') {
|
||||||
|
res.code = false
|
||||||
|
res.message = t('imageUrlTip')
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
if(!/^\d+.?\d{0,2}$/.test(diyStore.value[index].imageHeight)){
|
})
|
||||||
res.code = false;
|
return res
|
||||||
res.message = t('imageHeightRegNum');
|
}
|
||||||
return res;
|
|
||||||
}
|
diyStore.editComponent.list.forEach((item: any) => {
|
||||||
diyStore.value[index].list.forEach((item: any) => {
|
if (!item.id) item.id = diyStore.generateRandom()
|
||||||
if (item.imageUrl === '') {
|
})
|
||||||
res.code = false;
|
|
||||||
res.message = t('imageUrlTip');
|
watch(
|
||||||
return res;
|
() => diyStore.editComponent.list,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
// 设置图片宽高
|
||||||
|
handleHeight()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
const addImageAd = () => {
|
||||||
|
diyStore.editComponent.list.push({
|
||||||
|
id: diyStore.generateRandom(),
|
||||||
|
imageUrl: '',
|
||||||
|
imgWidth: 0,
|
||||||
|
imgHeight: 0,
|
||||||
|
link: { name: '' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectImg = (url:string) => {
|
||||||
|
handleHeight(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理高度
|
||||||
|
const handleHeight = (isCalcHeight:boolean = false)=> {
|
||||||
|
diyStore.editComponent.list.forEach((item: any, index: number) => {
|
||||||
|
const image = new Image()
|
||||||
|
image.src = img(item.imageUrl)
|
||||||
|
image.onload = async () => {
|
||||||
|
item.imgWidth = image.width
|
||||||
|
item.imgHeight = image.height
|
||||||
|
// 计算第一张图片高度
|
||||||
|
if (isCalcHeight && index == 0) {
|
||||||
|
const ratio = item.imgHeight / item.imgWidth
|
||||||
|
item.width = 375
|
||||||
|
item.height = item.width * ratio
|
||||||
|
diyStore.editComponent.imageHeight = parseInt(item.height)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
diyStore.editComponent.list.forEach((item: any) => {
|
|
||||||
if (!item.id) item.id = diyStore.generateRandom();
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
const blurImageHeight = () => {
|
||||||
() => diyStore.editComponent.list,
|
diyStore.editComponent.imageHeight = parseInt(diyStore.editComponent.imageHeight)
|
||||||
(newValue, oldValue) => {
|
}
|
||||||
// 设置图片宽高
|
|
||||||
handleHeight();
|
|
||||||
},
|
|
||||||
{deep: true}
|
|
||||||
)
|
|
||||||
|
|
||||||
const addImageAd = () => {
|
const imageBoxRef = ref()
|
||||||
diyStore.editComponent.list.push({
|
|
||||||
id: diyStore.generateRandom(),
|
onMounted(() => {
|
||||||
imageUrl: '',
|
nextTick(() => {
|
||||||
imgWidth: 0,
|
const sortable = Sortable.create(imageBoxRef.value, {
|
||||||
imgHeight: 0,
|
group: 'item-wrap',
|
||||||
link: {name: ''}
|
animation: 200,
|
||||||
|
onEnd: event => {
|
||||||
|
const temp = diyStore.editComponent.list[event.oldIndex!]
|
||||||
|
diyStore.editComponent.list.splice(event.oldIndex!, 1)
|
||||||
|
diyStore.editComponent.list.splice(event.newIndex!, 0, temp)
|
||||||
|
sortable.sort(
|
||||||
|
range(diyStore.editComponent.list.length).map(value => {
|
||||||
|
return value.toString()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
handleHeight(true)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const selectImg = (url:string)=> {
|
|
||||||
handleHeight(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理高度
|
|
||||||
const handleHeight = (isCalcHeight:boolean = false)=> {
|
|
||||||
diyStore.editComponent.list.forEach((item: any, index: number) => {
|
|
||||||
let image = new Image();
|
|
||||||
image.src = img(item.imageUrl);
|
|
||||||
image.onload = async () => {
|
|
||||||
item.imgWidth = image.width;
|
|
||||||
item.imgHeight = image.height;
|
|
||||||
// 计算第一张图片高度
|
|
||||||
if (isCalcHeight && index == 0) {
|
|
||||||
var ratio = item.imgHeight / item.imgWidth;
|
|
||||||
item.width = 375;
|
|
||||||
item.height = item.width * ratio;
|
|
||||||
diyStore.editComponent.imageHeight = parseInt(item.height);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const blurImageHeight = ()=> {
|
|
||||||
diyStore.editComponent.imageHeight = parseInt(diyStore.editComponent.imageHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageBoxRef = ref()
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
const sortable = Sortable.create(imageBoxRef.value, {
|
|
||||||
group: 'item-wrap',
|
|
||||||
animation: 200,
|
|
||||||
onEnd: event => {
|
|
||||||
const temp = diyStore.editComponent.list[event.oldIndex!];
|
|
||||||
diyStore.editComponent.list.splice(event.oldIndex!, 1);
|
|
||||||
diyStore.editComponent.list.splice(event.newIndex!, 0, temp);
|
|
||||||
sortable.sort(
|
|
||||||
range(diyStore.editComponent.list.length).map(value => {
|
|
||||||
return value.toString();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
handleHeight(true);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -28,13 +28,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,6 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 组件样式 -->
|
<!-- 组件样式 -->
|
||||||
<slot name="style"></slot>
|
<slot name="style"></slot>
|
||||||
</div>
|
</div>
|
||||||
@ -63,39 +62,39 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import {ref, reactive} from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
|
|
||||||
const showStyle = () => {
|
const showStyle = () => {
|
||||||
showDialog.value = true
|
showDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectStyle = ref(diyStore.editComponent.style)
|
||||||
|
|
||||||
|
const changeStyle = () => {
|
||||||
|
switch (selectStyle.value) {
|
||||||
|
case 'style-1':
|
||||||
|
diyStore.editComponent.subTitle.control = false
|
||||||
|
diyStore.editComponent.more.control = false
|
||||||
|
diyStore.editComponent.styleName = '风格1'
|
||||||
|
break
|
||||||
|
case 'style-2':
|
||||||
|
diyStore.editComponent.subTitle.control = true
|
||||||
|
diyStore.editComponent.more.control = true
|
||||||
|
diyStore.editComponent.styleName = '风格2'
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
diyStore.editComponent.style = selectStyle.value
|
||||||
|
showDialog.value = false
|
||||||
|
}
|
||||||
|
|
||||||
const selectStyle = ref(diyStore.editComponent.style)
|
defineExpose({})
|
||||||
|
|
||||||
const changeStyle = () => {
|
|
||||||
switch (selectStyle.value) {
|
|
||||||
case 'style-1':
|
|
||||||
diyStore.editComponent.subTitle.control = false
|
|
||||||
diyStore.editComponent.more.control = false
|
|
||||||
diyStore.editComponent.styleName = "风格1"
|
|
||||||
break;
|
|
||||||
case 'style-2':
|
|
||||||
diyStore.editComponent.subTitle.control = true
|
|
||||||
diyStore.editComponent.more.control = true
|
|
||||||
diyStore.editComponent.styleName = "风格2"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
diyStore.editComponent.style = selectStyle.value
|
|
||||||
showDialog.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -40,27 +40,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import {ref,watch} from 'vue'
|
import { watch } from 'vue'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => diyStore.global.bgUrl,
|
() => diyStore.global.bgUrl,
|
||||||
(newValue, oldValue) => {
|
(newValue, oldValue) => {
|
||||||
// 设置图片宽高
|
// 设置图片宽高
|
||||||
let image = new Image();
|
const image = new Image()
|
||||||
image.src = img(diyStore.global.bgUrl);
|
image.src = img(diyStore.global.bgUrl)
|
||||||
image.onload = async () => {
|
image.onload = async () => {
|
||||||
diyStore.global.imgWidth = image.width;
|
diyStore.global.imgWidth = image.width
|
||||||
diyStore.global.imgHeight = image.height;
|
diyStore.global.imgHeight = image.height
|
||||||
};
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
)
|
||||||
|
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<span>{{ selectTemplate.name }}</span>
|
<span>{{ selectTemplate.name }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<ul class="selected-template-list">
|
<ul class="selected-template-list">
|
||||||
<li v-for="(item,i) in templateList" :class="[(item.className == diyStore.editComponent.mode) ? 'selected' : '' ]" @click="changeTemplateList(i)">
|
<li v-for="(item,i) in templateList" :key="i" :class="[(item.className == diyStore.editComponent.mode) ? 'selected' : '' ]" @click="changeTemplateList(i)">
|
||||||
<icon :name="'iconfont-' + item.src" size="16px"/>
|
<icon :name="'iconfont-' + item.src" size="16px"/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
|
|
||||||
<ul class="layout">
|
<ul class="layout">
|
||||||
<li v-for="(li,i) in selectTemplate.dimensionScale" :class="[selectTemplate.className]" :style="{ width: rubikCubeList[i].widthStyle, height: rubikCubeList[i].imgHeight + 'px' }">
|
<li v-for="(li,i) in selectTemplate.dimensionScale" :key="i" :class="[selectTemplate.className]" :style="{ width: rubikCubeList[i].widthStyle, height: rubikCubeList[i].imgHeight + 'px' }">
|
||||||
<div class="have-preview-image" v-show="diyStore.editComponent.list[i].imageUrl">
|
<div class="have-preview-image" v-show="diyStore.editComponent.list[i].imageUrl">
|
||||||
<img class="!w-full !h-full" :src="img(diyStore.editComponent.list[i].imageUrl)"/>
|
<img class="!w-full !h-full" :src="img(diyStore.editComponent.list[i].imageUrl)"/>
|
||||||
</div>
|
</div>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div v-for="(item,index) in diyStore.editComponent.list" :key="item.id" class="item-wrap p-[10px] pb-0 relative border border-dashed border-gray-300 mb-[16px]">
|
<div v-for="(item) in diyStore.editComponent.list" :key="item.id" class="item-wrap p-[10px] pb-0 relative border border-dashed border-gray-300 mb-[16px]">
|
||||||
<el-form-item :label="t('image')">
|
<el-form-item :label="t('image')">
|
||||||
<upload-image v-model="item.imageUrl" :limit="1" @change="selectImg"/>
|
<upload-image v-model="item.imageUrl" :limit="1" @change="selectImg"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -72,423 +72,422 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, watch, onMounted, nextTick, computed} from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
// 组件验证
|
// 组件验证
|
||||||
diyStore.editComponent.verify = (index: number) => {
|
diyStore.editComponent.verify = (index: number) => {
|
||||||
var res = {code: true, message: ''};
|
const res = { code: true, message: '' }
|
||||||
diyStore.value[index].list.forEach((item: any) => {
|
diyStore.value[index].list.forEach((item: any) => {
|
||||||
if (item.imageUrl === '') {
|
if (item.imageUrl === '') {
|
||||||
res.code = false;
|
res.code = false
|
||||||
res.message = t('imageUrlTip');
|
res.message = t('imageUrlTip')
|
||||||
return res;
|
return res
|
||||||
}
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
const templateList = ref([
|
|
||||||
{
|
|
||||||
name: "1行2个",
|
|
||||||
src: 'iconyihangliangge',
|
|
||||||
className: "row1-of2",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:200px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "1行3个",
|
|
||||||
src: 'iconyihangsange',
|
|
||||||
className: "row1-of3",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度33.33%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度33.33%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度33.33%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图三"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:130px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "1行4个",
|
|
||||||
src: 'iconyihangsige',
|
|
||||||
className: "row1-of4",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度25%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度25%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度25%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图三"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度25%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图四"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:100px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "2左2右",
|
|
||||||
src: 'iconmofang-liangzuoliangyou',
|
|
||||||
className: "row2-lt-of2-rt",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图三"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图四"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:200px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "1左2右",
|
|
||||||
src: 'iconmofang-yizuoliangyou',
|
|
||||||
className: "row1-lt-of2-rt",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度100%",
|
|
||||||
size: "200px * 400px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图三"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,宽度最小建议为:200px,右侧两张图片高度一致,左侧图片高度为右侧两张图片高度之和(例:左侧图片尺寸:200px * 300px,右侧两张图片尺寸:200px * 150px)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "1上2下",
|
|
||||||
src: 'iconmofang-yishangliangxia',
|
|
||||||
className: "row1-tp-of2-bm",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度100% * 高度50%",
|
|
||||||
size: "400px * 200px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图三"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,上方一张图片的宽度为下方两张图片宽度之和,下放两张图片尺寸一致,高度可根据实际需求自行确定(例:上方图片尺寸:400px * 150px,下方两张图片尺寸:200px * 150px)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "1左3右",
|
|
||||||
src: 'iconxuanzemoban-yizuosanyou',
|
|
||||||
className: "row1-lt-of1-tp-of2-bm",
|
|
||||||
dimensionScale: [
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度100%",
|
|
||||||
size: "200px * 400px",
|
|
||||||
name: "图一"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度50% * 高度50%",
|
|
||||||
size: "200px * 200px",
|
|
||||||
name: "图二"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度25% * 高度50%",
|
|
||||||
size: "100px * 200px",
|
|
||||||
name: "图三"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "宽度25% * 高度50%",
|
|
||||||
size: "100px * 200px",
|
|
||||||
name: "图四"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
descAux: "选定布局区域,在下方添加图片,左右两侧内容宽高相同,右侧上下区域高度各占50%,右侧内容下半部分两张图片的宽度相同,各占右侧内容宽度的50%(例:左侧图片尺寸:200px * 400px,右侧上半部分图片尺寸:200px * 200px,右侧下半部分两张图片尺寸:100px * 200px)"
|
|
||||||
}
|
}
|
||||||
]);
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
let rubikCubeList = ref([]);
|
const templateList = ref([
|
||||||
const selectTemplate = computed(() => {
|
{
|
||||||
var data;
|
name: '1行2个',
|
||||||
templateList.value.forEach((item) => {
|
src: 'iconyihangliangge',
|
||||||
if (item.className == diyStore.editComponent.mode) {
|
className: 'row1-of2',
|
||||||
data = item;
|
dimensionScale: [
|
||||||
|
{
|
||||||
rubikCubeList.value = JSON.parse(JSON.stringify(diyStore.editComponent.list));
|
desc: '宽度50%',
|
||||||
if (item.className == 'row2-lt-of2-rt') {
|
size: '200px * 200px',
|
||||||
calcFourSquare();
|
name: '图一'
|
||||||
} else if (item.className == 'row1-lt-of2-rt') {
|
},
|
||||||
calcRowOneLeftOfTwoRight();
|
{
|
||||||
} else if (item.className == 'row1-tp-of2-bm') {
|
desc: '宽度50%',
|
||||||
calcRowOneTopOfTwoBottom();
|
size: '200px * 200px',
|
||||||
} else if (item.className == 'row1-lt-of1-tp-of2-bm') {
|
name: '图二'
|
||||||
calcRowOneLeftOfOneTopOfTwoBottom();
|
|
||||||
} else {
|
|
||||||
calcSingleRow(item.className);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
],
|
||||||
return data;
|
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:200px'
|
||||||
});
|
},
|
||||||
|
{
|
||||||
|
name: '1行3个',
|
||||||
|
src: 'iconyihangsange',
|
||||||
|
className: 'row1-of3',
|
||||||
|
dimensionScale: [
|
||||||
|
{
|
||||||
|
desc: '宽度33.33%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度33.33%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度33.33%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图三'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:130px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '1行4个',
|
||||||
|
src: 'iconyihangsige',
|
||||||
|
className: 'row1-of4',
|
||||||
|
dimensionScale: [
|
||||||
|
{
|
||||||
|
desc: '宽度25%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度25%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度25%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图三'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度25%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图四'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:100px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '2左2右',
|
||||||
|
src: 'iconmofang-liangzuoliangyou',
|
||||||
|
className: 'row2-lt-of2-rt',
|
||||||
|
dimensionScale: [
|
||||||
|
{
|
||||||
|
desc: '宽度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图三'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图四'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descAux: '选定布局区域,在下方添加图片,建议添加尺寸一致的图片,宽度最小建议为:200px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '1左2右',
|
||||||
|
src: 'iconmofang-yizuoliangyou',
|
||||||
|
className: 'row1-lt-of2-rt',
|
||||||
|
dimensionScale: [
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度100%',
|
||||||
|
size: '200px * 400px',
|
||||||
|
name: '图一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图三'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descAux: '选定布局区域,在下方添加图片,宽度最小建议为:200px,右侧两张图片高度一致,左侧图片高度为右侧两张图片高度之和(例:左侧图片尺寸:200px * 300px,右侧两张图片尺寸:200px * 150px)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '1上2下',
|
||||||
|
src: 'iconmofang-yishangliangxia',
|
||||||
|
className: 'row1-tp-of2-bm',
|
||||||
|
dimensionScale: [
|
||||||
|
{
|
||||||
|
desc: '宽度100% * 高度50%',
|
||||||
|
size: '400px * 200px',
|
||||||
|
name: '图一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图三'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descAux: '选定布局区域,在下方添加图片,上方一张图片的宽度为下方两张图片宽度之和,下放两张图片尺寸一致,高度可根据实际需求自行确定(例:上方图片尺寸:400px * 150px,下方两张图片尺寸:200px * 150px)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '1左3右',
|
||||||
|
src: 'iconxuanzemoban-yizuosanyou',
|
||||||
|
className: 'row1-lt-of1-tp-of2-bm',
|
||||||
|
dimensionScale: [
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度100%',
|
||||||
|
size: '200px * 400px',
|
||||||
|
name: '图一'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度50% * 高度50%',
|
||||||
|
size: '200px * 200px',
|
||||||
|
name: '图二'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度25% * 高度50%',
|
||||||
|
size: '100px * 200px',
|
||||||
|
name: '图三'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: '宽度25% * 高度50%',
|
||||||
|
size: '100px * 200px',
|
||||||
|
name: '图四'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
descAux: '选定布局区域,在下方添加图片,左右两侧内容宽高相同,右侧上下区域高度各占50%,右侧内容下半部分两张图片的宽度相同,各占右侧内容宽度的50%(例:左侧图片尺寸:200px * 400px,右侧上半部分图片尺寸:200px * 200px,右侧下半部分两张图片尺寸:100px * 200px)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
const changeTemplateList = (v: number) => {
|
const rubikCubeList = ref([])
|
||||||
for (var i = 0; i < templateList.value.length; i++) {
|
const selectTemplate = computed(() => {
|
||||||
if (i == v) {
|
let data
|
||||||
diyStore.editComponent.mode = templateList.value[i].className;
|
templateList.value.forEach((item) => {
|
||||||
var count = templateList.value[i].dimensionScale.length;
|
if (item.className == diyStore.editComponent.mode) {
|
||||||
|
data = item
|
||||||
|
|
||||||
//重置当前编辑的图片集合
|
rubikCubeList.value = JSON.parse(JSON.stringify(diyStore.editComponent.list))
|
||||||
|
if (item.className == 'row2-lt-of2-rt') {
|
||||||
|
calcFourSquare()
|
||||||
|
} else if (item.className == 'row1-lt-of2-rt') {
|
||||||
|
calcRowOneLeftOfTwoRight()
|
||||||
|
} else if (item.className == 'row1-tp-of2-bm') {
|
||||||
|
calcRowOneTopOfTwoBottom()
|
||||||
|
} else if (item.className == 'row1-lt-of1-tp-of2-bm') {
|
||||||
|
calcRowOneLeftOfOneTopOfTwoBottom()
|
||||||
|
} else {
|
||||||
|
calcSingleRow(item.className)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
})
|
||||||
|
|
||||||
//数量不够,进行添加
|
const changeTemplateList = (v: number) => {
|
||||||
if (count > diyStore.editComponent.list.length) {
|
for (let i = 0; i < templateList.value.length; i++) {
|
||||||
for (var j = 0; j < count; j++) {
|
if (i == v) {
|
||||||
if ((j + 1) > diyStore.editComponent.list.length) diyStore.editComponent.list.push({
|
diyStore.editComponent.mode = templateList.value[i].className
|
||||||
imageUrl: "",
|
const count = templateList.value[i].dimensionScale.length
|
||||||
|
|
||||||
|
// 重置当前编辑的图片集合
|
||||||
|
|
||||||
|
// 数量不够,进行添加
|
||||||
|
if (count > diyStore.editComponent.list.length) {
|
||||||
|
for (let j = 0; j < count; j++) {
|
||||||
|
if ((j + 1) > diyStore.editComponent.list.length) {
|
||||||
|
diyStore.editComponent.list.push({
|
||||||
|
imageUrl: '',
|
||||||
imgWidth: 0,
|
imgWidth: 0,
|
||||||
imgHeight: 0,
|
imgHeight: 0,
|
||||||
link: {name: ""}
|
link: { name: '' }
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
//数量不相同时,并且数量超出,减去
|
} else {
|
||||||
if (count != diyStore.editComponent.list.length) {
|
// 数量不相同时,并且数量超出,减去
|
||||||
for (var j = 0; j < diyStore.editComponent.list.length; j++) {
|
if (count != diyStore.editComponent.list.length) {
|
||||||
if ((j + 1) > count) {
|
for (let j = 0; j < diyStore.editComponent.list.length; j++) {
|
||||||
diyStore.editComponent.list.splice(j, 1);
|
if ((j + 1) > count) {
|
||||||
j = 0;
|
diyStore.editComponent.list.splice(j, 1)
|
||||||
}
|
j = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const selectImg = (url:string)=> {
|
|
||||||
handleHeight(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理高度
|
|
||||||
const handleHeight = (isCalcHeight:boolean = false)=> {
|
|
||||||
diyStore.editComponent.list.forEach((item: any, index: number) => {
|
|
||||||
let image = new Image();
|
|
||||||
image.src = img(item.imageUrl);
|
|
||||||
image.onload = async () => {
|
|
||||||
item.imgWidth = image.width;
|
|
||||||
item.imgHeight = image.height;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({})
|
const selectImg = (url:string) => {
|
||||||
|
handleHeight(true)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
// 处理高度
|
||||||
|
const handleHeight = (isCalcHeight:boolean = false) => {
|
||||||
|
diyStore.editComponent.list.forEach((item: any, index: number) => {
|
||||||
|
const image = new Image()
|
||||||
|
image.src = img(item.imageUrl)
|
||||||
|
image.onload = async () => {
|
||||||
|
item.imgWidth = image.width
|
||||||
|
item.imgHeight = image.height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({})
|
||||||
|
|
||||||
|
/**
|
||||||
* 魔方:单行多个,平分宽度
|
* 魔方:单行多个,平分宽度
|
||||||
* 公式:
|
* 公式:
|
||||||
* 宽度:屏幕宽度/2,示例:375/2=187.5
|
* 宽度:屏幕宽度/2,示例:375/2=187.5
|
||||||
* 比例:原图高/原图宽,示例:322/690=0.46
|
* 比例:原图高/原图宽,示例:322/690=0.46
|
||||||
* 高度:宽度*比例,示例:187.5*0.46=86.25
|
* 高度:宽度*比例,示例:187.5*0.46=86.25
|
||||||
*/
|
*/
|
||||||
const calcSingleRow = (type) => {
|
const calcSingleRow = (type:any) => {
|
||||||
let maxHeight = 0;
|
let maxHeight = 0
|
||||||
var paramsRatio = 2;
|
let paramsRatio = 2
|
||||||
var paramsWidth = 'calc(100% / 2)';
|
let paramsWidth = 'calc(100% / 2)'
|
||||||
if(type == 'row1-of3'){
|
if (type == 'row1-of3') {
|
||||||
paramsRatio = 3;
|
paramsRatio = 3
|
||||||
paramsWidth = 'calc(100% / 3)';
|
paramsWidth = 'calc(100% / 3)'
|
||||||
}
|
}
|
||||||
if(type == 'row1-of4'){
|
if (type == 'row1-of4') {
|
||||||
paramsRatio = 4
|
paramsRatio = 4
|
||||||
paramsWidth = 'calc(100% / 4)';
|
paramsWidth = 'calc(100% / 4)'
|
||||||
}
|
}
|
||||||
|
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
var ratio = item.imgHeight / item.imgWidth;
|
const ratio = item.imgHeight / item.imgWidth
|
||||||
|
|
||||||
let width = 330;
|
const width = 330
|
||||||
item.imgWidth = width / paramsRatio;
|
item.imgWidth = width / paramsRatio
|
||||||
item.imgHeight = item.imgWidth * ratio;
|
item.imgHeight = item.imgWidth * ratio
|
||||||
|
|
||||||
if (maxHeight == 0 || maxHeight < item.imgHeight) maxHeight = item.imgHeight;
|
if (maxHeight == 0 || maxHeight < item.imgHeight) maxHeight = item.imgHeight
|
||||||
})
|
})
|
||||||
|
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
item.widthStyle = paramsWidth;
|
item.widthStyle = paramsWidth
|
||||||
item.imgHeight = maxHeight;
|
item.imgHeight = maxHeight
|
||||||
});
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 魔方:四方型,各占50%
|
* 魔方:四方型,各占50%
|
||||||
*/
|
*/
|
||||||
const calcFourSquare = () => {
|
const calcFourSquare = () => {
|
||||||
let maxHeightFirst = 0;
|
let maxHeightFirst = 0
|
||||||
let maxHeightTwo = 0;
|
let maxHeightTwo = 0
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
var ratio = item.imgHeight / item.imgWidth;
|
const ratio = item.imgHeight / item.imgWidth
|
||||||
item.imgWidth = 330;
|
item.imgWidth = 330
|
||||||
item.imgWidth = item.imgWidth / 2;
|
item.imgWidth = item.imgWidth / 2
|
||||||
item.imgHeight = item.imgWidth * ratio;
|
item.imgHeight = item.imgWidth * ratio
|
||||||
|
|
||||||
|
// 获取每行最大高度
|
||||||
|
if (index <= 1) {
|
||||||
|
if (maxHeightFirst == 0 || maxHeightFirst < item.imgHeight) {
|
||||||
|
maxHeightFirst = item.imgHeight
|
||||||
|
}
|
||||||
|
} else if (index > 1) {
|
||||||
|
if (maxHeightTwo == 0 || maxHeightTwo < item.imgHeight) {
|
||||||
|
maxHeightTwo = item.imgHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
|
item.imgWidth = 'calc(100% / 2)'
|
||||||
|
item.widthStyle = item.imgWidth
|
||||||
|
if (index <= 1) {
|
||||||
|
item.imgHeight = maxHeightFirst
|
||||||
|
} else if (index > 1) {
|
||||||
|
item.imgHeight = maxHeightTwo
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 获取每行最大高度
|
/**
|
||||||
if (index <= 1) {
|
|
||||||
if (maxHeightFirst == 0 || maxHeightFirst < item.imgHeight) {
|
|
||||||
maxHeightFirst = item.imgHeight;
|
|
||||||
}
|
|
||||||
} else if (index > 1) {
|
|
||||||
if (maxHeightTwo == 0 || maxHeightTwo < item.imgHeight) {
|
|
||||||
maxHeightTwo = item.imgHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
|
||||||
item.imgWidth = 'calc(100% / 2)';
|
|
||||||
item.widthStyle = item.imgWidth;
|
|
||||||
if (index <= 1) {
|
|
||||||
item.imgHeight = maxHeightFirst;
|
|
||||||
} else if (index > 1) {
|
|
||||||
item.imgHeight = maxHeightTwo;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 魔方:1左2右
|
* 魔方:1左2右
|
||||||
*/
|
*/
|
||||||
const calcRowOneLeftOfTwoRight = () => {
|
const calcRowOneLeftOfTwoRight = () => {
|
||||||
let rightHeight = 0; // 右侧两图平分高度
|
let rightHeight = 0 // 右侧两图平分高度
|
||||||
let divide = 'left'; // 划分规则,left:左,right:右
|
let divide = 'left' // 划分规则,left:左,right:右
|
||||||
if (rubikCubeList.value[1].imgWidth === rubikCubeList.value[2].imgWidth) divide = 'right';
|
if (rubikCubeList.value[1].imgWidth === rubikCubeList.value[2].imgWidth) divide = 'right'
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
var ratio = item.imgHeight / item.imgWidth; // 获取左图的尺寸比例
|
const ratio = item.imgHeight / item.imgWidth // 获取左图的尺寸比例
|
||||||
item.imgWidth = 330;
|
item.imgWidth = 330
|
||||||
item.imgWidth = item.imgWidth / 2;
|
item.imgWidth = item.imgWidth / 2
|
||||||
item.imgHeight = item.imgWidth * ratio;
|
item.imgHeight = item.imgWidth * ratio
|
||||||
rightHeight = item.imgHeight / 2;
|
rightHeight = item.imgHeight / 2
|
||||||
item.imgWidth += 'px';
|
item.imgWidth += 'px'
|
||||||
} else {
|
} else {
|
||||||
item.imgWidth = rubikCubeList.value[0].imgWidth;
|
item.imgWidth = rubikCubeList.value[0].imgWidth
|
||||||
item.imgHeight = rightHeight;
|
item.imgHeight = rightHeight
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 魔方:1上2下
|
* 魔方:1上2下
|
||||||
*/
|
*/
|
||||||
const calcRowOneTopOfTwoBottom = () => {
|
const calcRowOneTopOfTwoBottom = () => {
|
||||||
var maxHeight = 0;
|
let maxHeight = 0
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
|
const ratio = item.imgHeight / item.imgWidth // 获取左图的尺寸比例
|
||||||
|
if (index == 0) {
|
||||||
|
item.imgWidth = 330
|
||||||
|
} else if (index > 0) {
|
||||||
|
item.imgWidth = 330
|
||||||
|
item.imgWidth = item.imgWidth / 2
|
||||||
|
}
|
||||||
|
|
||||||
var ratio = item.imgHeight / item.imgWidth; // 获取左图的尺寸比例
|
item.imgHeight = item.imgWidth * ratio
|
||||||
if (index == 0) {
|
|
||||||
item.imgWidth = 330;
|
|
||||||
} else if (index > 0) {
|
|
||||||
item.imgWidth = 330;
|
|
||||||
item.imgWidth = item.imgWidth / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.imgHeight = item.imgWidth * ratio;
|
// 获取最大高度
|
||||||
|
if (index > 0 && (maxHeight == 0 || maxHeight < item.imgHeight)) {
|
||||||
|
maxHeight = item.imgHeight
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
|
item.imgWidth += 'px'
|
||||||
|
item.widthStyle = item.imgWidth
|
||||||
|
if (index > 0) item.imgHeight = maxHeight
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 获取最大高度
|
/**
|
||||||
if (index > 0 && (maxHeight == 0 || maxHeight < item.imgHeight))
|
|
||||||
maxHeight = item.imgHeight;
|
|
||||||
|
|
||||||
});
|
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
|
||||||
item.imgWidth += 'px';
|
|
||||||
item.widthStyle = item.imgWidth;
|
|
||||||
if (index > 0) item.imgHeight = maxHeight;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 魔方:1左3右
|
* 魔方:1左3右
|
||||||
*/
|
*/
|
||||||
const calcRowOneLeftOfOneTopOfTwoBottom = () => {
|
const calcRowOneLeftOfOneTopOfTwoBottom = () => {
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
// 左图
|
// 左图
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
var ratio = item.imgHeight / item.imgWidth; // 获取左图的尺寸比例
|
const ratio = item.imgHeight / item.imgWidth // 获取左图的尺寸比例
|
||||||
item.imgWidth = 330;
|
item.imgWidth = 330
|
||||||
item.imgWidth = item.imgWidth / 2;
|
item.imgWidth = item.imgWidth / 2
|
||||||
item.imgHeight = item.imgWidth * ratio;
|
item.imgHeight = item.imgWidth * ratio
|
||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
item.imgWidth = rubikCubeList.value[0].imgWidth;
|
item.imgWidth = rubikCubeList.value[0].imgWidth
|
||||||
item.imgHeight = rubikCubeList.value[0].imgHeight / 2;
|
item.imgHeight = rubikCubeList.value[0].imgHeight / 2
|
||||||
} else if (index > 1) {
|
} else if (index > 1) {
|
||||||
item.imgWidth = rubikCubeList.value[0].imgWidth / 2;
|
item.imgWidth = rubikCubeList.value[0].imgWidth / 2
|
||||||
item.imgHeight = rubikCubeList.value[1].imgHeight;
|
item.imgHeight = rubikCubeList.value[1].imgHeight
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
rubikCubeList.value.forEach((item, index) => {
|
rubikCubeList.value.forEach((item:any, index) => {
|
||||||
item.imgWidth += 'px';
|
item.imgWidth += 'px'
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -5,9 +5,10 @@
|
|||||||
<h3 class="mb-[10px]">{{ t('styleSet') }}</h3>
|
<h3 class="mb-[10px]">{{ t('styleSet') }}</h3>
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
<el-form-item :label="t('selectStyle')" class="flex">
|
||||||
<span class="text-primary flex-1 cursor-pointer" @click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
<span class="text-primary flex-1 cursor-pointer" @click="showStyle">{{ diyStore.editComponent.styleName
|
||||||
|
}}</span>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<ArrowRight/>
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -16,15 +17,16 @@
|
|||||||
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
|
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
<el-form-item :label="t('title')">
|
<el-form-item :label="t('title')">
|
||||||
<el-input v-model="diyStore.editComponent.text" :placeholder="t('titlePlaceholder')" clearable maxlength="15" show-word-limit/>
|
<el-input v-model="diyStore.editComponent.text" :placeholder="t('titlePlaceholder')" clearable
|
||||||
|
maxlength="15" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('link')">
|
<el-form-item :label="t('link')">
|
||||||
<diy-link v-model="diyStore.editComponent.link"/>
|
<diy-link v-model="diyStore.editComponent.link" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('textAlign')" v-show="diyStore.editComponent.style == 'style-1'">
|
<el-form-item :label="t('textAlign')" v-show="diyStore.editComponent.style == 'style-1'">
|
||||||
<el-radio-group v-model="diyStore.editComponent.textAlign">
|
<el-radio-group v-model="diyStore.editComponent.textAlign">
|
||||||
<el-radio :label="'left'">{{t('textAlignLeft')}}</el-radio>
|
<el-radio :label="'left'">{{ t('textAlignLeft') }}</el-radio>
|
||||||
<el-radio :label="'center'">{{t('textAlignCenter')}}</el-radio>
|
<el-radio :label="'center'">{{ t('textAlignCenter') }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -34,13 +36,15 @@
|
|||||||
<h3 class="mb-[10px]">{{ t('subTitleContent') }}</h3>
|
<h3 class="mb-[10px]">{{ t('subTitleContent') }}</h3>
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
<el-form-item :label="t('subTitle')">
|
<el-form-item :label="t('subTitle')">
|
||||||
<el-input v-model="diyStore.editComponent.subTitle.text" :placeholder="t('subTitlePlaceholder')" clearable maxlength="30" show-word-limit/>
|
<el-input v-model="diyStore.editComponent.subTitle.text" :placeholder="t('subTitlePlaceholder')"
|
||||||
|
clearable maxlength="30" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('textFontSize')">
|
<el-form-item :label="t('textFontSize')">
|
||||||
<el-slider v-model="diyStore.editComponent.subTitle.fontSize" show-input size="small" class="ml-[10px] article-slider" :min="12" :max="16"/>
|
<el-slider v-model="diyStore.editComponent.subTitle.fontSize" show-input size="small"
|
||||||
|
class="ml-[10px] article-slider" :min="12" :max="16" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('textColor')">
|
<el-form-item :label="t('textColor')">
|
||||||
<el-color-picker v-model="diyStore.editComponent.subTitle.color"/>
|
<el-color-picker v-model="diyStore.editComponent.subTitle.color" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -49,16 +53,17 @@
|
|||||||
<h3 class="mb-[10px]">{{ t('moreContent') }}</h3>
|
<h3 class="mb-[10px]">{{ t('moreContent') }}</h3>
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
<el-form-item :label="t('more')">
|
<el-form-item :label="t('more')">
|
||||||
<el-input v-model="diyStore.editComponent.more.text" :placeholder="t('morePlaceholder')" clearable maxlength="8" show-word-limit/>
|
<el-input v-model="diyStore.editComponent.more.text" :placeholder="t('morePlaceholder')" clearable
|
||||||
|
maxlength="8" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('link')">
|
<el-form-item :label="t('link')">
|
||||||
<diy-link v-model="diyStore.editComponent.more.link"/>
|
<diy-link v-model="diyStore.editComponent.more.link" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('moreIsShow')">
|
<el-form-item :label="t('moreIsShow')">
|
||||||
<el-switch v-model="diyStore.editComponent.more.isShow"/>
|
<el-switch v-model="diyStore.editComponent.more.isShow" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('textColor')">
|
<el-form-item :label="t('textColor')">
|
||||||
<el-color-picker v-model="diyStore.editComponent.more.color"/>
|
<el-color-picker v-model="diyStore.editComponent.more.color" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -66,19 +71,21 @@
|
|||||||
<el-dialog v-model="showDialog" :title="t('selectStyle')" width="40%">
|
<el-dialog v-model="showDialog" :title="t('selectStyle')" width="40%">
|
||||||
|
|
||||||
<div class="flex flex-wrap">
|
<div class="flex flex-wrap">
|
||||||
<div class="flex items-center justify-center overflow-hidden w-[280px] h-[100px] mr-[12px] cursor-pointer border bg-gray-50" :class="{ 'border-primary' : selectStyle == 'style-1'}" @click="selectStyle = 'style-1'">
|
<div class="flex items-center justify-center overflow-hidden w-[280px] h-[100px] mr-[12px] cursor-pointer border bg-gray-50"
|
||||||
<img class="max-w-[280px] max-h-[220px]" src="@/app/assets/images/diy/text/style1.png"/>
|
:class="{ 'border-primary': selectStyle == 'style-1' }" @click="selectStyle = 'style-1'">
|
||||||
|
<img class="max-w-[280px] max-h-[220px]" src="@/app/assets/images/diy/text/style1.png" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-center overflow-hidden w-[280px] h-[100px] mr-[12px] cursor-pointer border bg-gray-50" :class="{ 'border-primary' : selectStyle == 'style-2'}" @click="selectStyle = 'style-2'">
|
<div class="flex items-center justify-center overflow-hidden w-[280px] h-[100px] mr-[12px] cursor-pointer border bg-gray-50"
|
||||||
<img class="max-w-[280px] max-h-[220px]" src="@/app/assets/images/diy/text/style2.png"/>
|
:class="{ 'border-primary': selectStyle == 'style-2' }" @click="selectStyle = 'style-2'">
|
||||||
|
<img class="max-w-[280px] max-h-[220px]" src="@/app/assets/images/diy/text/style2.png" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="showDialog = false">{{ t('cancel')}}</el-button>
|
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="changeStyle">{{ t('confirm') }}</el-button>
|
<el-button type="primary" @click="changeStyle">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -91,16 +98,17 @@
|
|||||||
<h3 class="mb-[10px]">{{ t('titleStyle') }}</h3>
|
<h3 class="mb-[10px]">{{ t('titleStyle') }}</h3>
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
<el-form-item :label="t('textFontSize')">
|
<el-form-item :label="t('textFontSize')">
|
||||||
<el-slider v-model="diyStore.editComponent.fontSize" show-input size="small" class="ml-[10px] article-slider" :min="12" :max="20"/>
|
<el-slider v-model="diyStore.editComponent.fontSize" show-input size="small"
|
||||||
|
class="ml-[10px] article-slider" :min="12" :max="20" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('textFontWeight')">
|
<el-form-item :label="t('textFontWeight')">
|
||||||
<el-radio-group v-model="diyStore.editComponent.fontWeight">
|
<el-radio-group v-model="diyStore.editComponent.fontWeight">
|
||||||
<el-radio :label="'normal'">{{t('fontWeightNormal')}}</el-radio>
|
<el-radio :label="'normal'">{{ t('fontWeightNormal') }}</el-radio>
|
||||||
<el-radio :label="'bold'">{{t('fontWeightBold')}}</el-radio>
|
<el-radio :label="'bold'">{{ t('fontWeightBold') }}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('textColor')">
|
<el-form-item :label="t('textColor')">
|
||||||
<el-color-picker v-model="diyStore.editComponent.textColor"/>
|
<el-color-picker v-model="diyStore.editComponent.textColor" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -109,51 +117,49 @@
|
|||||||
<slot name="style"></slot>
|
<slot name="style"></slot>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import {ref, reactive} from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
diyStore.editComponent.ignore = []; // 忽略公共属性
|
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
|
|
||||||
const showStyle = () => {
|
const showStyle = () => {
|
||||||
showDialog.value = true
|
showDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectStyle = ref(diyStore.editComponent.style)
|
||||||
|
|
||||||
|
const changeStyle = () => {
|
||||||
|
switch (selectStyle.value) {
|
||||||
|
case 'style-1':
|
||||||
|
diyStore.editComponent.subTitle.control = false
|
||||||
|
diyStore.editComponent.more.control = false
|
||||||
|
diyStore.editComponent.styleName = '风格1'
|
||||||
|
break
|
||||||
|
case 'style-2':
|
||||||
|
diyStore.editComponent.subTitle.control = true
|
||||||
|
diyStore.editComponent.more.control = true
|
||||||
|
diyStore.editComponent.styleName = '风格2'
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
diyStore.editComponent.style = selectStyle.value
|
||||||
|
showDialog.value = false
|
||||||
|
}
|
||||||
|
|
||||||
const selectStyle = ref(diyStore.editComponent.style)
|
defineExpose({})
|
||||||
|
|
||||||
const changeStyle = () => {
|
|
||||||
switch (selectStyle.value) {
|
|
||||||
case 'style-1':
|
|
||||||
diyStore.editComponent.subTitle.control = false
|
|
||||||
diyStore.editComponent.more.control = false
|
|
||||||
diyStore.editComponent.styleName = "风格1"
|
|
||||||
break;
|
|
||||||
case 'style-2':
|
|
||||||
diyStore.editComponent.subTitle.control = true
|
|
||||||
diyStore.editComponent.more.control = true
|
|
||||||
diyStore.editComponent.styleName = "风格2"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
diyStore.editComponent.style = selectStyle.value
|
|
||||||
showDialog.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({})
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.horz-blank-slider {
|
.horz-blank-slider {
|
||||||
.el-slider__input {
|
.el-slider__input {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
}</style>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,460 +1,457 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-wrap">
|
<div class="flex flex-wrap">
|
||||||
<div class="page-item relative bg-no-repeat ml-[20px] mr-[40px] mt-[20px] bg-[#f7f7f7] w-[300px] pt-[80px] pb-[20px]"
|
<div class="page-item relative bg-no-repeat ml-[20px] mr-[40px] mt-[20px] bg-[#f7f7f7] w-[300px] pt-[80px] pb-[20px]"
|
||||||
:class="{ 'cursor-pointer' : !item.isDisabledPop }" v-for="(item,key) in page" :key="key">
|
:class="{ 'cursor-pointer': !item.isDisabledPop }" v-for="(item, key) in page" :key="key">
|
||||||
<p class="absolute top-[46px] left-[50%] translate-x-[-50%] text-[14px] truncate w-[130px] text-center">
|
<p class="absolute top-[46px] left-[50%] translate-x-[-50%] text-[14px] truncate w-[130px] text-center">
|
||||||
{{item.use_template.title}}</p>
|
{{ item.use_template.title }}</p>
|
||||||
|
|
||||||
<div v-show="item.use_template.url" class="w-[282px] h-[493px] mx-auto">
|
<div v-show="item.use_template.url" class="w-[282px] h-[493px] mx-auto">
|
||||||
<iframe :id="'previewIframe_' + key" v-show="item.loadingIframe" class="w-[282px] h-[493px] mx-auto"
|
<iframe :id="'previewIframe_' + key" v-show="item.loadingIframe" class="w-[282px] h-[493px] mx-auto"
|
||||||
:src="item.use_template.wapPreview" frameborder="0"></iframe>
|
:src="item.use_template.wapPreview" frameborder="0"></iframe>
|
||||||
<div v-show="item.loadingDev" class="w-[282px] h-[493px] mx-auto bg-body pt-[20px] px-[20px]">
|
<div v-show="item.loadingDev" class="w-[282px] h-[493px] mx-auto bg-body pt-[20px] px-[20px]">
|
||||||
<div class="font-bold text-xl mb-[40px]">{{t('developTitle')}}</div>
|
<div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div>
|
||||||
<div class="mb-[20px] flex flex-col">
|
<div class="mb-[20px] flex flex-col">
|
||||||
<text class="mb-[10px]">{{ t('wapDomain') }}</text>
|
<text class="mb-[10px]">{{ t('wapDomain') }}</text>
|
||||||
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable/>
|
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-button type="primary" @click="saveDomain()">{{ t('confirm') }}</el-button>
|
<el-button type="primary" @click="saveDomain()">{{ t('confirm') }}</el-button>
|
||||||
<el-button type="primary" @click="settingTips()" plain>{{ t('settingTips') }}</el-button>
|
<el-button type="primary" @click="settingTips()" plain>{{ t('settingTips') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="!item.use_template.wapPreview" class="overflow-hidden w-[282px] h-[493px] mx-auto">
|
<div v-show="!item.use_template.wapPreview" class="overflow-hidden w-[282px] h-[493px] mx-auto">
|
||||||
<img class="max-w-full" v-if="item.use_template.cover" :src="img(item.use_template.cover)"/>
|
<img class="max-w-full" v-if="item.use_template.cover" :src="img(item.use_template.cover)" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="text-[12px] text-[#999] mt-[10px] mx-auto truncate text-center w-[250px]">
|
<p class="text-[12px] text-[#999] mt-[10px] mx-auto truncate text-center w-[250px]">
|
||||||
{{item.use_template.desc}}</p>
|
{{ item.use_template.desc }}</p>
|
||||||
|
|
||||||
<div class="item-hide absolute inset-x-0 inset-y-0 bg-black bg-opacity-50 text-center"
|
<div class="item-hide absolute inset-x-0 inset-y-0 bg-black bg-opacity-50 text-center"
|
||||||
:class="{ 'disabled' : item.isDisabledPop }">
|
:class="{ 'disabled': item.isDisabledPop }">
|
||||||
<div class="item-btn-box absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-col flex-wrap">
|
<div
|
||||||
<el-button @click="show(key,item)">{{ t('changePage') }}</el-button>
|
class="item-btn-box absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] flex flex-col flex-wrap">
|
||||||
<el-button @click="toDecorate(item.use_template)"
|
<el-button @click="show(key, item)">{{ t('changePage') }}</el-button>
|
||||||
v-show="item.use_template.mode != 'other' || item.use_template.action == 'decorate'">{{
|
<el-button @click="toDecorate(item.use_template)"
|
||||||
t('decorate') }}
|
v-show="item.use_template.mode != 'other' || item.use_template.action == 'decorate'">{{
|
||||||
</el-button>
|
t('decorate') }}
|
||||||
<el-button @click="toPreview(item.use_template)">{{ t('preview') }}</el-button>
|
</el-button>
|
||||||
</div>
|
<el-button @click="toPreview(item.use_template)">{{ t('preview') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog v-model="showDialog" :title="t('changeTemplate')" width="400px" :close-on-press-escape="false"
|
<el-dialog v-model="showDialog" :title="t('changeTemplate')" width="400px" :close-on-press-escape="false"
|
||||||
:destroy-on-close="true" :close-on-click-modal="false">
|
:destroy-on-close="true" :close-on-click-modal="false">
|
||||||
|
|
||||||
<el-form :model="form" label-width="0px" v-if="formData.type">
|
<el-form :model="form" label-width="0px" v-if="formData.type">
|
||||||
<el-form-item label="">
|
<el-form-item label="">
|
||||||
<div>{{t('hopeBeforeTip')}}<span class="text-primary px-[5px]">{{ page[formData.type].title }}</span>{{t('hopeAfterTip')}}
|
<div>{{ t('hopeBeforeTip') }}<span class="text-primary px-[5px]">{{ page[formData.type].title
|
||||||
</div>
|
}}</span>{{ t('hopeAfterTip') }}
|
||||||
</el-form-item>
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="">
|
<el-form-item label="">
|
||||||
<el-select v-model="hope" class="w-full">
|
<el-select v-model="hope" class="w-full">
|
||||||
<el-option :label="t('changeTemplateTip') + ' ' + page[formData.type].title + ' ' + t('template')"
|
<el-option :label="t('changeTemplateTip') + ' ' + page[formData.type].title + ' ' + t('template')"
|
||||||
value="template"/>
|
value="template" />
|
||||||
<el-option :label="t('changeMyPageTip') + ' ' + page[formData.type].title" value="diy"/>
|
<el-option :label="t('changeMyPageTip') + ' ' + page[formData.type].title" value="diy" />
|
||||||
<el-option :label="t('changeOtherPageTip') + ' ' + page[formData.type].title" value="other"/>
|
<el-option :label="t('changeOtherPageTip') + ' ' + page[formData.type].title" value="other" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="" v-show="hope == 'template'">
|
<el-form-item label="" v-show="hope == 'template'">
|
||||||
<el-select v-model="formData.template" class="w-full">
|
<el-select v-model="formData.template" class="w-full">
|
||||||
<el-option v-for="(item, key) in page[formData.type].template" :label="item.title" :value="key"/>
|
<el-option v-for="(item, key) in page[formData.type].template" :label="item.title" :value="key" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="" v-show="hope == 'diy'">
|
<el-form-item label="" v-show="hope == 'diy'">
|
||||||
<el-select v-model="formData.id" class="w-full">
|
<el-select v-model="formData.id" class="w-full">
|
||||||
<el-option v-for="(item, index) in page[formData.type].my_page" :label="item.title"
|
<el-option v-for="(item, index) in page[formData.type].my_page" :label="item.title" :value="item.id" :key="index" />
|
||||||
:value="item.id"/>
|
</el-select>
|
||||||
</el-select>
|
<div class="mt-[10px]">
|
||||||
<div class="mt-[10px]">
|
<span class="cursor-pointer text-primary mr-[10px]" @click="toDiyList">{{ t('createPage') }}</span>
|
||||||
<span class="cursor-pointer text-primary mr-[10px]" @click="toDiyList">{{ t('createPage') }}</span>
|
<span class="cursor-pointer text-primary" @click="refreshMyPage">{{ t('refreshPage') }}</span>
|
||||||
<span class="cursor-pointer text-primary" @click="refreshMyPage">{{ t('refreshPage') }}</span>
|
</div>
|
||||||
</div>
|
</el-form-item>
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="" v-show="hope == 'other'">
|
<el-form-item label="" v-show="hope == 'other'">
|
||||||
<el-select v-model="formData.page" class="w-full">
|
<el-select v-model="formData.page" class="w-full">
|
||||||
<el-option v-for="(item, index) in page[formData.type].other_page" :label="item.title"
|
<el-option v-for="(item, index) in page[formData.type].other_page" :label="item.title"
|
||||||
:value="item.page"/>
|
:value="item.page" :key="index" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="showDialog = false">{{ t('cancel')}}</el-button>
|
|
||||||
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<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 {img} from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import {useRouter} from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import {ElMessage} from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import {getDecoratePage, getDiyList, changeTemplate} from '@/app/api/diy'
|
import { getDecoratePage, getDiyList, changeTemplate } from '@/app/api/diy'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
|
|
||||||
const page: any = reactive({})
|
const page: any = reactive({})
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const hope = ref('template')
|
const hope = ref('template')
|
||||||
const wapDomain = ref('')
|
const wapDomain = ref('')
|
||||||
|
|
||||||
// 添加自定义页面
|
// 添加自定义页面
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
name: '',
|
name: '',
|
||||||
mode: '',
|
mode: '',
|
||||||
template: '',
|
template: '',
|
||||||
id: '',
|
id: '',
|
||||||
page: '',
|
page: '',
|
||||||
title: '',
|
title: '',
|
||||||
action: ''
|
action: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
const refreshData = () => {
|
const refreshData = () => {
|
||||||
formData.type = '';
|
formData.type = ''
|
||||||
formData.name = '';
|
formData.name = ''
|
||||||
formData.mode = '';
|
formData.mode = ''
|
||||||
formData.template = '';
|
formData.template = ''
|
||||||
formData.id = '';
|
formData.id = ''
|
||||||
formData.page = '';
|
formData.page = ''
|
||||||
formData.title = '';
|
formData.title = ''
|
||||||
formData.action = '';
|
formData.action = ''
|
||||||
getDecoratePage({}).then((res => {
|
getDecoratePage({}).then(res => {
|
||||||
for (let key in res.data) {
|
for (const key in res.data) {
|
||||||
page[key] = res.data[key]
|
page[key] = res.data[key]
|
||||||
}
|
|
||||||
|
|
||||||
for (let key in page) {
|
|
||||||
if (page[key].use_template.url) {
|
|
||||||
|
|
||||||
page[key].loadingIframe = false; // 加载iframe
|
|
||||||
page[key].loadingDev = false; // 加载开发环境配置
|
|
||||||
page[key].isDisabledPop = false; // 是否禁止打开遮罩层
|
|
||||||
page[key].difference = 0; // 检测页面加载差异,小于1000毫秒,则配置wap端域名
|
|
||||||
|
|
||||||
wapDomain.value = page[key].domain_url.wap_domain;
|
|
||||||
page[key].wapUrl = page[key].domain_url.wap_url;
|
|
||||||
|
|
||||||
if (import.meta.env.MODE == 'development') {
|
|
||||||
// 开发模式情况下,并且未配置wap域名,则获取缓存域名
|
|
||||||
if (wapDomain.value) {
|
|
||||||
page[key].wapUrl = wapDomain.value + '/wap';
|
|
||||||
setDomain(key);
|
|
||||||
}
|
|
||||||
if (storage.get('wap_domain')) {
|
|
||||||
page[key].wapUrl = storage.get('wap_domain')
|
|
||||||
setDomain(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setDomain(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshData();
|
|
||||||
|
|
||||||
// 监听 uni-app 端 是否加载完成
|
|
||||||
window.addEventListener('message', (event) => {
|
|
||||||
try {
|
|
||||||
let data = JSON.parse(event.data);
|
|
||||||
if (['appOnLaunch', 'appOnReady'].indexOf(data.type) != -1) {
|
|
||||||
for (let key in page) {
|
|
||||||
page[key].loadingDev = false; // 禁用开发环境配置
|
|
||||||
page[key].loadingIframe = true; // 加载iframe
|
|
||||||
var loadTime = new Date().getTime();
|
|
||||||
page[key].difference = loadTime - page[key].timeIframe;
|
|
||||||
page[key].isDisabledPop = false; // 是否禁止打开遮罩层
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
for (let key in page) {
|
|
||||||
initLoad(key);
|
|
||||||
}
|
|
||||||
console.log('后台接受数据错误', e)
|
|
||||||
}
|
}
|
||||||
}, false);
|
|
||||||
|
|
||||||
// 将数据发送到uniapp
|
for (const key in page) {
|
||||||
const postMessage = (key: string) => {
|
if (page[key].use_template.url) {
|
||||||
var diyData = JSON.stringify({
|
page[key].loadingIframe = false // 加载iframe
|
||||||
type: 'appOnReady',
|
page[key].loadingDev = false // 加载开发环境配置
|
||||||
message: '加载完成'
|
page[key].isDisabledPop = false // 是否禁止打开遮罩层
|
||||||
});
|
page[key].difference = 0 // 检测页面加载差异,小于1000毫秒,则配置wap端域名
|
||||||
if (window['previewIframe_' + key]) window['previewIframe_' + key].contentWindow.postMessage(diyData, '*');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始化加载状态
|
wapDomain.value = page[key].domain_url.wap_domain
|
||||||
const initLoad = (key: string) => {
|
page[key].wapUrl = page[key].domain_url.wap_url
|
||||||
page[key].loadingDev = true;
|
|
||||||
page[key].isDisabledPop = true;
|
if (import.meta.env.MODE == 'development') {
|
||||||
page[key].loadingIframe = false;
|
// 开发模式情况下,并且未配置wap域名,则获取缓存域名
|
||||||
|
if (wapDomain.value) {
|
||||||
|
page[key].wapUrl = wapDomain.value + '/wap'
|
||||||
|
setDomain(key)
|
||||||
|
}
|
||||||
|
if (storage.get('wap_domain')) {
|
||||||
|
page[key].wapUrl = storage.get('wap_domain')
|
||||||
|
setDomain(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setDomain(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshData()
|
||||||
|
|
||||||
|
// 监听 uni-app 端 是否加载完成
|
||||||
|
window.addEventListener('message', (event) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data)
|
||||||
|
if (['appOnLaunch', 'appOnReady'].indexOf(data.type) != -1) {
|
||||||
|
for (const key in page) {
|
||||||
|
page[key].loadingDev = false // 禁用开发环境配置
|
||||||
|
page[key].loadingIframe = true // 加载iframe
|
||||||
|
const loadTime = new Date().getTime()
|
||||||
|
page[key].difference = loadTime - page[key].timeIframe
|
||||||
|
page[key].isDisabledPop = false // 是否禁止打开遮罩层
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
for (const key in page) {
|
||||||
|
initLoad(key)
|
||||||
|
}
|
||||||
|
console.log('后台接受数据错误', e)
|
||||||
}
|
}
|
||||||
|
}, false)
|
||||||
|
|
||||||
const saveDomain = () => {
|
// 将数据发送到uniapp
|
||||||
if (wapDomain.value.trim().length == 0) {
|
const postMessage = (key: string) => {
|
||||||
|
const diyData = JSON.stringify({
|
||||||
|
type: 'appOnReady',
|
||||||
|
message: '加载完成'
|
||||||
|
})
|
||||||
|
if (window['previewIframe_' + key]) window['previewIframe_' + key].contentWindow.postMessage(diyData, '*')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化加载状态
|
||||||
|
const initLoad = (key: string) => {
|
||||||
|
page[key].loadingDev = true
|
||||||
|
page[key].isDisabledPop = true
|
||||||
|
page[key].loadingIframe = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveDomain = () => {
|
||||||
|
if (wapDomain.value.trim().length == 0) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: `${t('wapDomainPlaceholder')}`,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const wapUrl = wapDomain.value + '/wap'
|
||||||
|
storage.set({ key: 'wap_domain', data: wapUrl })
|
||||||
|
|
||||||
|
for (const key in page) {
|
||||||
|
if (page[key].use_template.url) {
|
||||||
|
page[key].wapUrl = wapUrl
|
||||||
|
setDomain(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
for (const key in page) {
|
||||||
|
if (page[key].use_template.url) {
|
||||||
|
page[key].loadingIframe = true // 加载iframe
|
||||||
|
page[key].loadingDev = false // 加载开发环境配置
|
||||||
|
page[key].isDisabledPop = false // 是否禁止打开遮罩层
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100 * 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingTips = () => {
|
||||||
|
window.open('https://www.kancloud.cn/niucloud/niucloud-admin-develop/3213393')
|
||||||
|
}
|
||||||
|
|
||||||
|
const setDomain = (key: string) => {
|
||||||
|
page[key].use_template.wapPreview = page[key].wapUrl + page[key].use_template.url
|
||||||
|
page[key].timeIframe = new Date().getTime()
|
||||||
|
postMessage(key)
|
||||||
|
setTimeout(() => {
|
||||||
|
if (page[key].difference == 0) initLoad(key)
|
||||||
|
}, 1000 * 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const show = (key: string, data: any) => {
|
||||||
|
// 每次打开时赋值
|
||||||
|
showDialog.value = true
|
||||||
|
|
||||||
|
hope.value = data.use_template.hope
|
||||||
|
formData.type = key
|
||||||
|
formData.name = data.use_template.name
|
||||||
|
formData.mode = data.use_template.mode
|
||||||
|
formData.action = data.use_template.action
|
||||||
|
|
||||||
|
if (hope.value == 'template') {
|
||||||
|
formData.template = data.use_template.template
|
||||||
|
} else if (hope.value == 'diy') {
|
||||||
|
formData.id = data.use_template.id
|
||||||
|
} else if (hope.value == 'other') {
|
||||||
|
formData.page = data.use_template.page
|
||||||
|
formData.title = data.use_template.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转去装修
|
||||||
|
const toDecorate = (data: any) => {
|
||||||
|
const query: any = {
|
||||||
|
back: '/site/diy/index'
|
||||||
|
}
|
||||||
|
if (data.id) {
|
||||||
|
query.id = data.id
|
||||||
|
} else if (data.name) {
|
||||||
|
query.name = data.name
|
||||||
|
} else if (data.url) {
|
||||||
|
query.url = data.url
|
||||||
|
}
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/decorate/edit',
|
||||||
|
query
|
||||||
|
})
|
||||||
|
window.open(url.href)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转去预览
|
||||||
|
const toPreview = (data: any) => {
|
||||||
|
let page = data.page
|
||||||
|
if (data.url) {
|
||||||
|
page = data.url
|
||||||
|
} else if (data.id) {
|
||||||
|
page += '?id=' + data.id
|
||||||
|
}
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/preview/wap',
|
||||||
|
query: {
|
||||||
|
page
|
||||||
|
}
|
||||||
|
})
|
||||||
|
window.open(url.href)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建微页面
|
||||||
|
const toDiyList = (data: any) => {
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/diy/list'
|
||||||
|
})
|
||||||
|
window.open(url.href)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新我的微页面
|
||||||
|
const refreshMyPage = () => {
|
||||||
|
getDiyList({ type: formData.type }).then((res) => {
|
||||||
|
let isExist = true // 检测选择的微页面是否存在,不存在则清空
|
||||||
|
for (let i = 0; i < res.data.length; i++) {
|
||||||
|
if (formData.id == res.data[i].id) {
|
||||||
|
isExist = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isExist) {
|
||||||
|
formData.id = ''
|
||||||
|
}
|
||||||
|
page[formData.type].my_page = {}
|
||||||
|
Object.assign(page[formData.type].my_page, res.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => hope.value,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
// 选择某个,清空其余
|
||||||
|
if (newValue == 'template') {
|
||||||
|
// 选择模板
|
||||||
|
formData.id = ''
|
||||||
|
formData.page = ''
|
||||||
|
formData.action = 'decorate'
|
||||||
|
formData.name = formData.type
|
||||||
|
} else if (newValue == 'diy') {
|
||||||
|
// 选择微页面
|
||||||
|
formData.mode = 'diy'
|
||||||
|
formData.template = ''
|
||||||
|
formData.page = ''
|
||||||
|
formData.action = 'decorate'
|
||||||
|
formData.name = formData.type
|
||||||
|
} else if (newValue == 'other') {
|
||||||
|
// 选择其他页面
|
||||||
|
formData.mode = 'other'
|
||||||
|
formData.template = ''
|
||||||
|
formData.id = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听模板变化
|
||||||
|
watch(
|
||||||
|
() => formData.template,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue) {
|
||||||
|
formData.mode = page[formData.type].template[newValue].mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听其他页面
|
||||||
|
watch(
|
||||||
|
() => formData.page,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (newValue) {
|
||||||
|
for (let i = 0; i < page[formData.type].other_page.length; i++) {
|
||||||
|
if (page[formData.type].other_page[i].page == newValue) {
|
||||||
|
formData.name = page[formData.type].other_page[i].name
|
||||||
|
formData.title = page[formData.type].other_page[i].title
|
||||||
|
formData.action = page[formData.type].other_page[i].action
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const isRepeat = ref(false)
|
||||||
|
const save = () => {
|
||||||
|
if (hope.value == 'template') {
|
||||||
|
if (formData.template == '') {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: `${t('wapDomainPlaceholder')}`,
|
message: `${t('placeholderTemplate')}`
|
||||||
});
|
})
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
let wapUrl = wapDomain.value + '/wap';
|
} else if (hope.value == 'diy') {
|
||||||
storage.set({key: 'wap_domain', data: wapUrl});
|
if (formData.id == '') {
|
||||||
|
ElMessage({
|
||||||
for (let key in page) {
|
type: 'warning',
|
||||||
if (page[key].use_template.url) {
|
message: `${t('placeholderMyPage')}`
|
||||||
page[key].wapUrl = wapUrl;
|
})
|
||||||
setDomain(key);
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
} else if (hope.value == 'other') {
|
||||||
for (let key in page) {
|
if (formData.page == '') {
|
||||||
if (page[key].use_template.url) {
|
ElMessage({
|
||||||
page[key].loadingIframe = true; // 加载iframe
|
type: 'warning',
|
||||||
page[key].loadingDev = false; // 加载开发环境配置
|
message: `${t('placeholderOtherPage')}`
|
||||||
page[key].isDisabledPop = false; // 是否禁止打开遮罩层
|
})
|
||||||
}
|
return
|
||||||
}
|
|
||||||
}, 100 * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
const settingTips = () => {
|
|
||||||
window.open('https://www.kancloud.cn/niucloud/niucloud-admin-develop/3213393')
|
|
||||||
}
|
|
||||||
|
|
||||||
const setDomain = (key: string) => {
|
|
||||||
page[key].use_template.wapPreview = page[key].wapUrl + page[key].use_template.url;
|
|
||||||
page[key].timeIframe = new Date().getTime();
|
|
||||||
postMessage(key);
|
|
||||||
setTimeout(() => {
|
|
||||||
if (page[key].difference == 0) initLoad(key);
|
|
||||||
}, 1000 * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
const show = (key: string, data: any) => {
|
|
||||||
// 每次打开时赋值
|
|
||||||
showDialog.value = true;
|
|
||||||
|
|
||||||
hope.value = data.use_template.hope;
|
|
||||||
formData.type = key;
|
|
||||||
formData.name = data.use_template.name;
|
|
||||||
formData.mode = data.use_template.mode;
|
|
||||||
formData.action = data.use_template.action;
|
|
||||||
|
|
||||||
if (hope.value == 'template') {
|
|
||||||
formData.template = data.use_template.template;
|
|
||||||
} else if (hope.value == 'diy') {
|
|
||||||
formData.id = data.use_template.id;
|
|
||||||
} else if (hope.value == 'other') {
|
|
||||||
formData.page = data.use_template.page;
|
|
||||||
formData.title = data.use_template.title;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转去装修
|
if (isRepeat.value) return
|
||||||
const toDecorate = (data: any) => {
|
isRepeat.value = true
|
||||||
let query: any = {
|
|
||||||
back: '/site/diy/index'
|
|
||||||
};
|
|
||||||
if (data.id) {
|
|
||||||
query.id = data.id;
|
|
||||||
} else if (data.name) {
|
|
||||||
query.name = data.name;
|
|
||||||
} else if (data.url) {
|
|
||||||
query.url = data.url;
|
|
||||||
}
|
|
||||||
let url = router.resolve({
|
|
||||||
path: '/decorate/edit',
|
|
||||||
query
|
|
||||||
});
|
|
||||||
window.open(url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转去预览
|
changeTemplate({
|
||||||
const toPreview = (data: any) => {
|
...formData
|
||||||
let page = data.page;
|
}).then((res) => {
|
||||||
if (data.url) {
|
isRepeat.value = false
|
||||||
page = data.url;
|
showDialog.value = false
|
||||||
} else if (data.id) {
|
refreshData()
|
||||||
page += '?id=' + data.id;
|
})
|
||||||
}
|
}
|
||||||
let url = router.resolve({
|
|
||||||
path: '/preview/wap',
|
|
||||||
query: {
|
|
||||||
page
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.open(url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建微页面
|
|
||||||
const toDiyList = (data: any) => {
|
|
||||||
let url = router.resolve({
|
|
||||||
path: '/diy/list'
|
|
||||||
});
|
|
||||||
window.open(url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 刷新我的微页面
|
|
||||||
const refreshMyPage = () => {
|
|
||||||
getDiyList({type: formData.type}).then((res) => {
|
|
||||||
let isExist = true; // 检测选择的微页面是否存在,不存在则清空
|
|
||||||
for (let i = 0; i < res.data.length; i++) {
|
|
||||||
if (formData.id == res.data[i].id) {
|
|
||||||
isExist = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isExist) {
|
|
||||||
formData.id = '';
|
|
||||||
}
|
|
||||||
page[formData.type].my_page = {};
|
|
||||||
Object.assign(page[formData.type].my_page, res.data);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => hope.value,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// 选择某个,清空其余
|
|
||||||
if (newValue == 'template') {
|
|
||||||
// 选择模板
|
|
||||||
formData.id = '';
|
|
||||||
formData.page = '';
|
|
||||||
formData.action = 'decorate';
|
|
||||||
formData.name = formData.type;
|
|
||||||
} else if (newValue == 'diy') {
|
|
||||||
// 选择微页面
|
|
||||||
formData.mode = 'diy';
|
|
||||||
formData.template = '';
|
|
||||||
formData.page = '';
|
|
||||||
formData.action = 'decorate';
|
|
||||||
formData.name = formData.type;
|
|
||||||
} else if (newValue == 'other') {
|
|
||||||
// 选择其他页面
|
|
||||||
formData.mode = 'other';
|
|
||||||
formData.template = '';
|
|
||||||
formData.id = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 监听模板变化
|
|
||||||
watch(
|
|
||||||
() => formData.template,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
if (newValue) {
|
|
||||||
formData.mode = page[formData.type].template[newValue].mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 监听其他页面
|
|
||||||
watch(
|
|
||||||
() => formData.page,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
if (newValue) {
|
|
||||||
for (let i = 0; i < page[formData.type].other_page.length; i++) {
|
|
||||||
if (page[formData.type].other_page[i].page == newValue) {
|
|
||||||
formData.name = page[formData.type].other_page[i].name;
|
|
||||||
formData.title = page[formData.type].other_page[i].title;
|
|
||||||
formData.action = page[formData.type].other_page[i].action;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const isRepeat = ref(false)
|
|
||||||
const save = () => {
|
|
||||||
if (hope.value == 'template') {
|
|
||||||
if (formData.template == '') {
|
|
||||||
ElMessage({
|
|
||||||
type: 'warning',
|
|
||||||
message: `${t('placeholderTemplate')}`,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (hope.value == 'diy') {
|
|
||||||
if (formData.id == '') {
|
|
||||||
ElMessage({
|
|
||||||
type: 'warning',
|
|
||||||
message: `${t('placeholderMyPage')}`,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (hope.value == 'other') {
|
|
||||||
if (formData.page == '') {
|
|
||||||
ElMessage({
|
|
||||||
type: 'warning',
|
|
||||||
message: `${t('placeholderOtherPage')}`,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRepeat.value) return
|
|
||||||
isRepeat.value = true
|
|
||||||
|
|
||||||
changeTemplate({
|
|
||||||
...formData
|
|
||||||
}).then((res) => {
|
|
||||||
isRepeat.value = false;
|
|
||||||
showDialog.value = false;
|
|
||||||
refreshData();
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.page-item {
|
.page-item {
|
||||||
|
|
||||||
background-image: url(@/app/assets/images/iphone_bg.png);
|
background-image: url(@/app/assets/images/iphone_bg.png);
|
||||||
background-color: var(--el-bg-color);
|
background-color: var(--el-bg-color);
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
|
|
||||||
.item-hide {
|
.item-hide {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
.item-btn-box {
|
.item-btn-box {
|
||||||
|
|
||||||
button {
|
button {
|
||||||
height: 35px;
|
height: 35px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
|
|
||||||
& ~ button {
|
&~button {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.item-hide:not(.disabled) {
|
.item-hide:not(.disabled) {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,338 +1,337 @@
|
|||||||
<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">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">
|
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">
|
||||||
{{ t('addDiyPage') }}
|
{{ t('addDiyPage') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef">
|
<el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef">
|
||||||
<el-form-item :label="t('title')" prop="title">
|
<el-form-item :label="t('title')" prop="title">
|
||||||
<el-input v-model="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')"/>
|
<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, key) in pageType" :label="item.title" :value="key"/>
|
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadDiyPageList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadDiyPageList()">{{ t('search') }}</el-button>
|
||||||
<el-button @click="resetForm(searchFormDiyPageRef)">{{ t('reset') }}</el-button>
|
<el-button @click="resetForm(searchFormDiyPageRef)">{{ t('reset') }}</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-table :data="diyPageTableData.data" size="large" v-loading="diyPageTableData.loading">
|
<el-table :data="diyPageTableData.data" size="large" v-loading="diyPageTableData.loading">
|
||||||
|
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<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="80">-->
|
<!-- <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>-->
|
||||||
<!-- <span v-if="row.is_default == 1" class="text-primary">{{ t('isUse') }}</span>-->
|
<!-- <span v-if="row.is_default == 1" class="text-primary">{{ t('isUse') }}</span>-->
|
||||||
<!-- <span v-else>{{ t('unused') }}</span>-->
|
<!-- <span v-else>{{ t('unused') }}</span>-->
|
||||||
<!-- </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" align="right" min-width="160">
|
<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="toPreview(row)">{{ t('promote') }}</el-button>
|
<el-button type="primary" link @click="toPreview(row)">{{ t('promote') }}</el-button>
|
||||||
<el-button v-if="row.type == 'DIY_PAGE'" type="primary" link @click="openShare(row)">{{
|
<el-button v-if="row.type == 'DIY_PAGE'" type="primary" link @click="openShare(row)">{{
|
||||||
t('shareSet') }}
|
t('shareSet') }}
|
||||||
</el-button>
|
</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>-->
|
||||||
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
|
<el-button type="primary" 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"
|
<el-pagination v-model:current-page="diyPageTableData.page" v-model:page-size="diyPageTableData.limit"
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="diyPageTableData.total"
|
layout="total, sizes, prev, pager, next, jumper" :total="diyPageTableData.total"
|
||||||
@size-change="loadDiyPageList()" @current-change="loadDiyPageList"/>
|
@size-change="loadDiyPageList()" @current-change="loadDiyPageList" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!--添加页面-->
|
<!--添加页面-->
|
||||||
<el-dialog v-model="dialogVisible" :title="t('addPageTips')" width="25%">
|
<el-dialog v-model="dialogVisible" :title="t('addPageTips')" width="25%">
|
||||||
|
|
||||||
<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('title')" prop="title">
|
<el-form-item :label="t('title')" prop="title">
|
||||||
<el-input v-model="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12"
|
<el-input v-model="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12"
|
||||||
show-word-limit class="w-full"/>
|
show-word-limit class="w-full" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('addType')" prop="type">
|
<el-form-item :label="t('addType')" prop="type">
|
||||||
<el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')" class="w-full">
|
<el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')" class="w-full">
|
||||||
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key"/>
|
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('templateName')" prop="template" v-show="pageTypeData">
|
<el-form-item :label="t('templateName')" prop="template" v-show="pageTypeData">
|
||||||
<el-select v-model="formData.template" class="w-full">
|
<el-select v-model="formData.template" class="w-full">
|
||||||
<el-option :label="t('emptyTemplate')" value=""/>
|
<el-option :label="t('emptyTemplate')" value="" />
|
||||||
<el-option v-for="(item, key) in pageTypeData" :label="item.title" :value="key"/>
|
<el-option v-for="(item, key) in pageTypeData" :label="item.title" :value="key" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</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>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 分享设置-->
|
<!-- 分享设置-->
|
||||||
<el-dialog v-model="shareDialogVisible" :title="t('shareSet')" width="30%">
|
<el-dialog v-model="shareDialogVisible" :title="t('shareSet')" width="30%">
|
||||||
<el-tabs v-model="tabShareType">
|
<el-tabs v-model="tabShareType">
|
||||||
<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-form :model="shareFormData[tabShareType]" label-width="90px" ref="shareFormRef" :rules="shareFormRules">
|
<el-form :model="shareFormData[tabShareType]" label-width="90px" ref="shareFormRef" :rules="shareFormRules">
|
||||||
<el-form-item :label="t('sharePage')">
|
<el-form-item :label="t('sharePage')">
|
||||||
<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')"
|
<el-input v-model="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')"
|
||||||
clearable maxlength="30" show-word-limit/>
|
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')"
|
<el-input v-model="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')"
|
||||||
type="textarea" rows="4" clearable maxlength="100" show-word-limit/>
|
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>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {reactive, ref, computed} from 'vue'
|
import { reactive, ref, computed } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import {getDiyPageList, deleteDiyPage, getDiyTemplate, editDiyPageShare} from '@/app/api/diy'
|
import { getDiyPageList, deleteDiyPage, getDiyTemplate, editDiyPageShare } from '@/app/api/diy'
|
||||||
import {ElMessageBox, FormInstance} from 'element-plus'
|
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import {getUrl} from '@/app/api/sys'
|
import { getUrl } from '@/app/api/sys'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
const pageType: any = reactive({}) // 页面模板类型
|
const pageType: any = reactive({}) // 页面模板类型
|
||||||
|
|
||||||
// 添加自定义页面
|
// 添加自定义页面
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
|
title: '',
|
||||||
|
type: '',
|
||||||
|
template: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const formRules = computed(() => {
|
||||||
|
return {
|
||||||
|
title: [
|
||||||
|
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' }
|
||||||
|
],
|
||||||
|
type: [
|
||||||
|
{ required: true, message: t('pageTypePlaceholder'), trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageTypeData = computed(() => {
|
||||||
|
let data: any = ''
|
||||||
|
formData.template = ''
|
||||||
|
if (formData.type) {
|
||||||
|
data = pageType[formData.type].template
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const addEvent = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
|
||||||
|
await formEl.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
dialogVisible.value = false
|
||||||
|
let url = `/decorate/edit?type=${formData.type}&title=${formData.title}`
|
||||||
|
if (formData.template) url += `&template=${formData.template}`
|
||||||
|
router.push(url)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const wapDomain = ref('')
|
||||||
|
const getDomain = async () => {
|
||||||
|
wapDomain.value = (await getUrl()).data.wap_url
|
||||||
|
}
|
||||||
|
getDomain()
|
||||||
|
|
||||||
|
// 获取自定义页面模板
|
||||||
|
getDiyTemplate({ mode: '' }).then(res => {
|
||||||
|
for (const key in res.data) {
|
||||||
|
pageType[key] = res.data[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const diyPageTableData: any = reactive({
|
||||||
|
page: 1,
|
||||||
|
limit: 10,
|
||||||
|
total: 0,
|
||||||
|
loading: true,
|
||||||
|
data: [],
|
||||||
|
searchParam: {
|
||||||
title: '',
|
title: '',
|
||||||
type: '',
|
type: '',
|
||||||
template: ''
|
mode: ''
|
||||||
})
|
|
||||||
|
|
||||||
// 表单验证规则
|
|
||||||
const formRules = computed(() => {
|
|
||||||
return {
|
|
||||||
title: [
|
|
||||||
{required: true, message: t('titlePlaceholder'), trigger: 'blur'},
|
|
||||||
],
|
|
||||||
type: [
|
|
||||||
{required: true, message: t('pageTypePlaceholder'), trigger: 'blur'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const pageTypeData = computed(() => {
|
|
||||||
let data: any = '';
|
|
||||||
formData.template = '';
|
|
||||||
if (formData.type) {
|
|
||||||
data = pageType[formData.type].template;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
})
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
const dialogVisible = ref(false)
|
|
||||||
const addEvent = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return
|
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
|
||||||
if (valid) {
|
|
||||||
dialogVisible.value = false;
|
|
||||||
let url = `/decorate/edit?type=${formData.type}&title=${formData.title}`;
|
|
||||||
if (formData.template) url += `&template=${formData.template}`;
|
|
||||||
router.push(url);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const wapDomain = ref('')
|
const searchFormDiyPageRef = ref<FormInstance>()
|
||||||
const getDomain = async () => {
|
|
||||||
wapDomain.value = (await getUrl()).data.wap_url;
|
|
||||||
};
|
|
||||||
getDomain();
|
|
||||||
|
|
||||||
// 获取自定义页面模板
|
// 获取自定义页面列表
|
||||||
getDiyTemplate({mode: ''}).then(res => {
|
const loadDiyPageList = (page: number = 1) => {
|
||||||
for (let key in res.data) {
|
diyPageTableData.loading = true
|
||||||
pageType[key] = res.data[key]
|
diyPageTableData.page = page
|
||||||
}
|
|
||||||
|
getDiyPageList({
|
||||||
|
page: diyPageTableData.page,
|
||||||
|
limit: diyPageTableData.limit,
|
||||||
|
...diyPageTableData.searchParam
|
||||||
|
}).then(res => {
|
||||||
|
diyPageTableData.loading = false
|
||||||
|
diyPageTableData.data = res.data.data
|
||||||
|
diyPageTableData.total = res.data.total
|
||||||
|
}).catch(() => {
|
||||||
|
diyPageTableData.loading = false
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
let diyPageTableData: any = reactive({
|
loadDiyPageList()
|
||||||
page: 1,
|
|
||||||
limit: 10,
|
// 编辑自定义页面
|
||||||
total: 0,
|
const editEvent = (data: any) => {
|
||||||
loading: true,
|
const url = router.resolve({
|
||||||
data: [],
|
path: '/decorate/edit',
|
||||||
searchParam: {
|
query: { id: data.id }
|
||||||
"title": "",
|
|
||||||
"type": '',
|
|
||||||
'mode': ''
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
window.open(url.href)
|
||||||
|
}
|
||||||
|
|
||||||
const searchFormDiyPageRef = ref<FormInstance>()
|
// 删除自定义页面
|
||||||
|
const deleteEvent = (id: number) => {
|
||||||
// 获取自定义页面列表
|
ElMessageBox.confirm(t('diyPageDeleteTips'), t('warning'),
|
||||||
const loadDiyPageList = (page: number = 1) => {
|
{
|
||||||
diyPageTableData.loading = true
|
confirmButtonText: t('confirm'),
|
||||||
diyPageTableData.page = page
|
cancelButtonText: t('cancel'),
|
||||||
|
type: 'warning'
|
||||||
getDiyPageList({
|
}
|
||||||
page: diyPageTableData.page,
|
).then(() => {
|
||||||
limit: diyPageTableData.limit,
|
deleteDiyPage(id).then(() => {
|
||||||
...diyPageTableData.searchParam
|
loadDiyPageList()
|
||||||
}).then(res => {
|
|
||||||
diyPageTableData.loading = false
|
|
||||||
diyPageTableData.data = res.data.data
|
|
||||||
diyPageTableData.total = res.data.total
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
diyPageTableData.loading = false
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转去预览
|
||||||
|
const toPreview = (data: any) => {
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/preview/wap',
|
||||||
|
query: {
|
||||||
|
page: data.type_page + '?id=' + data.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
window.open(url.href)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabShareType = ref('wechat')
|
||||||
|
const sharePage = ref('')
|
||||||
|
const shareFormId = ref(0)
|
||||||
|
const shareFormData = reactive({
|
||||||
|
wechat: {
|
||||||
|
title: '',
|
||||||
|
desc: '',
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
weapp: {
|
||||||
|
title: '',
|
||||||
|
url: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const shareDialogVisible = ref(false)
|
||||||
|
const shareFormRules = computed(() => {
|
||||||
|
return {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const shareFormRef = ref<FormInstance>()
|
||||||
|
const openShare = async (row: any) => {
|
||||||
|
shareFormId.value = row.id
|
||||||
|
sharePage.value = row.title
|
||||||
|
const share = row.share ? JSON.parse(row.share) : {
|
||||||
|
wechat: { title: '', desc: '', url: '' },
|
||||||
|
weapp: { title: '', url: '' }
|
||||||
|
}
|
||||||
|
if (share) {
|
||||||
|
shareFormData.wechat = share.wechat
|
||||||
|
shareFormData.weapp = share.weapp
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDiyPageList()
|
shareDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
// 编辑自定义页面
|
const shareEvent = async (formEl: FormInstance | undefined) => {
|
||||||
const editEvent = (data: any) => {
|
if (!formEl) return
|
||||||
let url = router.resolve({
|
|
||||||
path: '/decorate/edit',
|
|
||||||
query: {id: data.id}
|
|
||||||
});
|
|
||||||
window.open(url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除自定义页面
|
await formEl.validate(async (valid) => {
|
||||||
const deleteEvent = (id: number) => {
|
if (valid) {
|
||||||
ElMessageBox.confirm(t('diyPageDeleteTips'), t('warning'),
|
editDiyPageShare({
|
||||||
{
|
id: shareFormId.value,
|
||||||
confirmButtonText: t('confirm'),
|
share: JSON.stringify(shareFormData)
|
||||||
cancelButtonText: t('cancel'),
|
}).then(() => {
|
||||||
type: 'warning',
|
|
||||||
}
|
|
||||||
).then(() => {
|
|
||||||
deleteDiyPage(id).then(() => {
|
|
||||||
loadDiyPageList()
|
loadDiyPageList()
|
||||||
|
shareDialogVisible.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转去预览
|
|
||||||
const toPreview = (data: any) => {
|
|
||||||
let url = router.resolve({
|
|
||||||
path: '/preview/wap',
|
|
||||||
query: {
|
|
||||||
page: data.type_page + '?id=' + data.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.open(url.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
const tabShareType = ref('wechat')
|
|
||||||
const sharePage = ref('')
|
|
||||||
const shareFormId = ref(0)
|
|
||||||
const shareFormData = reactive({
|
|
||||||
wechat: {
|
|
||||||
title: '',
|
|
||||||
desc: '',
|
|
||||||
url: ''
|
|
||||||
},
|
|
||||||
weapp: {
|
|
||||||
title: '',
|
|
||||||
url: ''
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const shareDialogVisible = ref(false)
|
}
|
||||||
const shareFormRules = computed(() => {
|
|
||||||
return {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const shareFormRef = ref<FormInstance>()
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
const openShare = async (row: any) => {
|
if (!formEl) return
|
||||||
shareFormId.value = row.id;
|
formEl.resetFields()
|
||||||
sharePage.value = row.title;
|
loadDiyPageList()
|
||||||
let share = row.share ? JSON.parse(row.share) : {
|
}
|
||||||
wechat: {title: '', desc: '', url: ''},
|
|
||||||
weapp: {title: '', url: ''}
|
|
||||||
};
|
|
||||||
if (share) {
|
|
||||||
shareFormData.wechat = share.wechat;
|
|
||||||
shareFormData.weapp = share.weapp;
|
|
||||||
}
|
|
||||||
|
|
||||||
shareDialogVisible.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const shareEvent = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return
|
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
|
||||||
if (valid) {
|
|
||||||
editDiyPageShare({
|
|
||||||
id: shareFormId.value,
|
|
||||||
share: JSON.stringify(shareFormData),
|
|
||||||
}).then(() => {
|
|
||||||
loadDiyPageList()
|
|
||||||
shareDialogVisible.value = false;
|
|
||||||
}).catch(() => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return
|
|
||||||
formEl.resetFields();
|
|
||||||
loadDiyPageList();
|
|
||||||
}
|
|
||||||
|
|
||||||
</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>
|
|
||||||
@ -53,140 +53,140 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, reactive, watch} from 'vue'
|
import { ref, reactive, watch } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import {useRoute} from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import {getWeappConfig} from '@/app/api/weapp'
|
import { getWeappConfig } from '@/app/api/weapp'
|
||||||
import {getUrl} from '@/app/api/sys'
|
import { getUrl } from '@/app/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 QRCode from "qrcode";
|
import QRCode from 'qrcode'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import {getPreviewData} from '@/app/api/diy'
|
import { getPreviewData } from '@/app/api/diy'
|
||||||
|
|
||||||
const wapUrl = ref('')
|
const wapUrl = ref('')
|
||||||
const wapDomain = ref('')
|
const wapDomain = ref('')
|
||||||
const wapImage = ref('')
|
const wapImage = ref('')
|
||||||
const wapPreview = ref('')
|
const wapPreview = ref('')
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const loadingIframe = ref(false) // 加载iframe
|
const loadingIframe = ref(false) // 加载iframe
|
||||||
const loadingDev = ref(false) // 加载开发环境配置
|
const loadingDev = ref(false) // 加载开发环境配置
|
||||||
const timeFrame = ref(0)
|
const timeFrame = ref(0)
|
||||||
|
|
||||||
var time = new Date().getTime();
|
let time = new Date().getTime()
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
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 || ''
|
||||||
|
|
||||||
getUrl().then((res: any) => {
|
getUrl().then((res: any) => {
|
||||||
wapDomain.value = res.data.wap_domain;
|
wapDomain.value = res.data.wap_domain
|
||||||
wapUrl.value = res.data.wap_url;
|
wapUrl.value = res.data.wap_url
|
||||||
setDomain();
|
setDomain()
|
||||||
|
|
||||||
// 生产模式禁止
|
// 生产模式禁止
|
||||||
if (import.meta.env.MODE == 'production') return;
|
if (import.meta.env.MODE == 'production') return
|
||||||
|
|
||||||
// env文件配置过wap域名
|
// env文件配置过wap域名
|
||||||
if (wapDomain.value) return;
|
if (wapDomain.value) return
|
||||||
|
|
||||||
let wap_domain_storage = storage.get('wap_domain');
|
let wap_domain_storage = storage.get('wap_domain')
|
||||||
if (wap_domain_storage) {
|
if (wap_domain_storage) {
|
||||||
wapUrl.value = wap_domain_storage
|
wapUrl.value = wap_domain_storage
|
||||||
setDomain();
|
setDomain()
|
||||||
return;
|
return
|
||||||
}
|
|
||||||
|
|
||||||
timeFrame.value = new Date().getTime();
|
|
||||||
});
|
|
||||||
|
|
||||||
const save = () => {
|
|
||||||
if (wapDomain.value.trim().length == 0) {
|
|
||||||
ElMessage({
|
|
||||||
type: 'warning',
|
|
||||||
message: `${t('wapDomainPlaceholder')}`,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wapUrl.value = wapDomain.value + '/wap';
|
|
||||||
setDomain();
|
|
||||||
storage.set({key: 'wap_domain', data: wapUrl.value});
|
|
||||||
loadingIframe.value = true;
|
|
||||||
loadingDev.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const setDomain = () => {
|
timeFrame.value = new Date().getTime()
|
||||||
getPreviewData({
|
})
|
||||||
id: route.query.id,
|
|
||||||
name: route.query.name,
|
|
||||||
}).then((res: any) => {
|
|
||||||
let data = res.data;
|
|
||||||
wapPreview.value = `${wapUrl.value}/${data.page}`;
|
|
||||||
|
|
||||||
// 开发模式增加站点id
|
const save = () => {
|
||||||
if (import.meta.env.MODE == 'development') {
|
if (wapDomain.value.trim().length == 0) {
|
||||||
let siteId = storage.get('siteId') || 0;
|
ElMessage({
|
||||||
wapPreview.value += `&site_id=${siteId}`;
|
type: 'warning',
|
||||||
}
|
message: `${t('wapDomainPlaceholder')}`
|
||||||
QRCode.toDataURL(wapPreview.value, {errorCorrectionLevel: 'L', margin: 0, width: 100}).then(url => {
|
})
|
||||||
wapImage.value = url
|
return
|
||||||
})
|
}
|
||||||
|
wapUrl.value = wapDomain.value + '/wap'
|
||||||
|
setDomain()
|
||||||
|
storage.set({ key: 'wap_domain', data: wapUrl.value })
|
||||||
|
loadingIframe.value = true
|
||||||
|
loadingDev.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const setDomain = () => {
|
||||||
|
getPreviewData({
|
||||||
|
id: route.query.id,
|
||||||
|
name: route.query.name
|
||||||
|
}).then((res: any) => {
|
||||||
|
const data = res.data
|
||||||
|
wapPreview.value = `${wapUrl.value}/${data.page}`
|
||||||
|
|
||||||
|
// 开发模式增加站点id
|
||||||
|
if (import.meta.env.MODE == 'development') {
|
||||||
|
const siteId = storage.get('siteId') || 0
|
||||||
|
wapPreview.value += `&site_id=${siteId}`
|
||||||
|
}
|
||||||
|
QRCode.toDataURL(wapPreview.value, { errorCorrectionLevel: 'L', margin: 0, width: 100 }).then(url => {
|
||||||
|
wapImage.value = url
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听iframe加载事件
|
||||||
|
const loadIframe = () => {
|
||||||
|
if (!wapPreview.value) return
|
||||||
|
const loadTime = new Date().getTime()
|
||||||
|
const difference = loadTime - timeFrame.value
|
||||||
|
// 检测页面加载差异,小于1000毫秒,则配置wap端域名
|
||||||
|
if (difference < 1000) {
|
||||||
|
loadingDev.value = true
|
||||||
|
loadingIframe.value = false
|
||||||
|
wapPreview.value = ''
|
||||||
|
wapImage.value = ''
|
||||||
|
} else {
|
||||||
|
loadingDev.value = false
|
||||||
|
loadingIframe.value = true
|
||||||
|
}
|
||||||
|
loading.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const weappConfig = reactive({
|
||||||
|
qr_code: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const previewMode = ref('weapp')
|
||||||
|
|
||||||
|
// 获取微信配置
|
||||||
|
getWeappConfig().then((res: any) => {
|
||||||
|
if (res.code == 1) {
|
||||||
|
const data = res.data
|
||||||
|
weappConfig.qr_code = data.qr_code
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 复制
|
||||||
|
const { copy, isSupported, copied } = useClipboard()
|
||||||
|
const copyEvent = (text: string) => {
|
||||||
|
if (!isSupported.value) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('notSupportCopy'),
|
||||||
|
type: 'warning'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
copy(text)
|
||||||
|
}
|
||||||
|
|
||||||
// 监听iframe加载事件
|
watch(copied, () => {
|
||||||
const loadIframe = () => {
|
if (copied.value) {
|
||||||
if (!wapPreview.value) return;
|
ElMessage({
|
||||||
var loadTime = new Date().getTime();
|
message: t('copySuccess'),
|
||||||
var difference = loadTime - timeFrame.value;
|
type: 'success'
|
||||||
// 检测页面加载差异,小于1000毫秒,则配置wap端域名
|
})
|
||||||
if (difference < 1000) {
|
|
||||||
loadingDev.value = true;
|
|
||||||
loadingIframe.value = false;
|
|
||||||
wapPreview.value = '';
|
|
||||||
wapImage.value = '';
|
|
||||||
} else {
|
|
||||||
loadingDev.value = false;
|
|
||||||
loadingIframe.value = true;
|
|
||||||
}
|
|
||||||
loading.value = true
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
const weappConfig = reactive({
|
|
||||||
qr_code: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const previewMode = ref('weapp')
|
|
||||||
|
|
||||||
// 获取微信配置
|
|
||||||
getWeappConfig().then((res: any) => {
|
|
||||||
if (res.code == 1) {
|
|
||||||
let data = res.data;
|
|
||||||
weappConfig.qr_code = data.qr_code;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 复制
|
|
||||||
const {copy, isSupported, copied} = useClipboard()
|
|
||||||
const copyEvent = (text: string) => {
|
|
||||||
if (!isSupported.value) {
|
|
||||||
ElMessage({
|
|
||||||
message: t('notSupportCopy'),
|
|
||||||
type: 'warning'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
copy(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(copied, () => {
|
|
||||||
if (copied.value) {
|
|
||||||
ElMessage({
|
|
||||||
message: t('copySuccess'),
|
|
||||||
type: 'success'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -83,7 +83,7 @@
|
|||||||
import { reactive, ref, watch, computed } from 'vue'
|
import { reactive, ref, watch, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getDiyTemplate, getDiyRouteList, getDiyRouteInfo, editDiyRouteShare } from '@/app/api/diy'
|
import { getDiyTemplate, getDiyRouteList, getDiyRouteInfo, editDiyRouteShare } from '@/app/api/diy'
|
||||||
import { ElMessage, FormInstance, ElMessageBox } from 'element-plus'
|
import { ElMessage, FormInstance } from 'element-plus'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useClipboard } from '@vueuse/core'
|
import { useClipboard } from '@vueuse/core'
|
||||||
import { getUrl } from '@/app/api/sys'
|
import { getUrl } from '@/app/api/sys'
|
||||||
@ -91,28 +91,28 @@ import { getUrl } from '@/app/api/sys'
|
|||||||
const pageTemplate: any = reactive({})
|
const pageTemplate: any = reactive({})
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
|
|
||||||
let diyRouteTableData = reactive({
|
const diyRouteTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam: {
|
searchParam: {
|
||||||
"title": "",
|
title: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const wapDomain = ref('')
|
const wapDomain = ref('')
|
||||||
const getDomain = async () => {
|
const getDomain = async () => {
|
||||||
wapDomain.value = (await getUrl()).data.wap_url;
|
wapDomain.value = (await getUrl()).data.wap_url
|
||||||
};
|
}
|
||||||
|
|
||||||
getDomain();
|
getDomain()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取自定义路由列表
|
* 获取自定义路由列表
|
||||||
@ -126,15 +126,15 @@ const loadDiyRouteList = (page: number = 1) => {
|
|||||||
limit: diyRouteTableData.limit,
|
limit: diyRouteTableData.limit,
|
||||||
...diyRouteTableData.searchParam
|
...diyRouteTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
diyRouteTableData.loading = false;
|
diyRouteTableData.loading = false
|
||||||
|
|
||||||
let len = Math.ceil(res.data.length / diyRouteTableData.limit);
|
const len = Math.ceil(res.data.length / diyRouteTableData.limit)
|
||||||
let data = JSON.parse(JSON.stringify(res.data));
|
const data = JSON.parse(JSON.stringify(res.data))
|
||||||
let dataGather = [];
|
const dataGather = []
|
||||||
for(var i = 0; i < len; i++){
|
for (let i = 0; i < len; i++) {
|
||||||
dataGather[i] = data.splice(0, diyRouteTableData.limit);
|
dataGather[i] = data.splice(0, diyRouteTableData.limit)
|
||||||
}
|
}
|
||||||
diyRouteTableData.data = dataGather[diyRouteTableData.page-1];
|
diyRouteTableData.data = dataGather[diyRouteTableData.page - 1]
|
||||||
|
|
||||||
diyRouteTableData.total = res.data.length
|
diyRouteTableData.total = res.data.length
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@ -145,7 +145,7 @@ loadDiyRouteList()
|
|||||||
|
|
||||||
// 获取自定义页面模板
|
// 获取自定义页面模板
|
||||||
getDiyTemplate({}).then(res => {
|
getDiyTemplate({}).then(res => {
|
||||||
for (let key in res.data) {
|
for (const key in res.data) {
|
||||||
pageTemplate[key] = res.data[key]
|
pageTemplate[key] = res.data[key]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -204,12 +204,12 @@ const shareFormRules = computed(() => {
|
|||||||
const shareFormRef = ref<FormInstance>()
|
const shareFormRef = ref<FormInstance>()
|
||||||
const openShare = async (row: any) => {
|
const openShare = async (row: any) => {
|
||||||
// 基础页面
|
// 基础页面
|
||||||
let info = (await getDiyRouteInfo({
|
const info = (await getDiyRouteInfo({
|
||||||
name: row.name
|
name: row.name
|
||||||
})).data;
|
})).data
|
||||||
|
|
||||||
if (info.title) {
|
if (info.title) {
|
||||||
row.id = info.id;
|
row.id = info.id
|
||||||
row.title = info.title
|
row.title = info.title
|
||||||
row.name = info.name
|
row.name = info.name
|
||||||
row.page = info.page
|
row.page = info.page
|
||||||
@ -224,18 +224,18 @@ const openShare = async (row: any) => {
|
|||||||
diyRouteData.is_share = row.is_share
|
diyRouteData.is_share = row.is_share
|
||||||
diyRouteData.sort = row.sort
|
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) : {
|
const 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
|
||||||
shareFormData.weapp = share.weapp;
|
shareFormData.weapp = share.weapp
|
||||||
}
|
}
|
||||||
|
|
||||||
shareDialogVisible.value = true;
|
shareDialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const shareEvent = async (formEl: FormInstance | undefined) => {
|
const shareEvent = async (formEl: FormInstance | undefined) => {
|
||||||
@ -243,24 +243,24 @@ const shareEvent = async (formEl: FormInstance | undefined) => {
|
|||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let save = editDiyRouteShare
|
const save = editDiyRouteShare
|
||||||
save({
|
save({
|
||||||
id: shareFormId.value,
|
id: shareFormId.value,
|
||||||
share: JSON.stringify(shareFormData),
|
share: JSON.stringify(shareFormData),
|
||||||
...diyRouteData
|
...diyRouteData
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
loadDiyRouteList()
|
loadDiyRouteList()
|
||||||
shareDialogVisible.value = false;
|
shareDialogVisible.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadDiyRouteList();
|
loadDiyRouteList()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,18 +2,18 @@
|
|||||||
<div class="error">
|
<div class="error">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<slot name="content">
|
<slot name="content">
|
||||||
<div>
|
<div>
|
||||||
<img class="w-[300px]" src="@/app/assets/images/error.png"/>
|
<img class="w-[300px]" src="@/app/assets/images/error.png" />
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
<div class="text-left ml-[100px]">
|
<div class="text-left ml-[100px]">
|
||||||
<div class="error-text text-[28px] font-bold">404错误!</div>
|
<div class="error-text text-[28px] font-bold">404错误!</div>
|
||||||
<div class="text-[#222] text-[20px] mt-[15px]">哎呀,出错了!您访问的页面不存在...</div>
|
<div class="text-[#222] text-[20px] mt-[15px]">哎呀,出错了!您访问的页面不存在...</div>
|
||||||
<div class="text-[#c4c2c2] text-[12px] mt-[5px]">尝试检查URL的错误,然后点击浏览器刷新按钮。</div>
|
<div class="text-[#c4c2c2] text-[12px] mt-[5px]">尝试检查URL的错误,然后点击浏览器刷新按钮。</div>
|
||||||
<div class="mt-[40px]">
|
<div class="mt-[40px]">
|
||||||
<el-button class="bottom" @click="router.go(-1)">{{ second }} 秒后返回上一页</el-button>
|
<el-button class="bottom" @click="router.go(-1)">{{ second }} 秒后返回上一页</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -53,13 +53,15 @@ onUnmounted(() => {
|
|||||||
@apply text-primary;
|
@apply text-primary;
|
||||||
font-size: 150px;
|
font-size: 150px;
|
||||||
}
|
}
|
||||||
.error-text {
|
|
||||||
color:#0e77fd;
|
.error-text {
|
||||||
}
|
color: #0e77fd;
|
||||||
|
}
|
||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
width: 176px;
|
width: 176px;
|
||||||
background-color: #0e77fd;
|
background-color: #0e77fd;
|
||||||
color:#fff
|
color: #fff
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,230 +1,196 @@
|
|||||||
<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">
|
||||||
|
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
||||||
<el-row class="flex">
|
<el-row class="flex">
|
||||||
<el-col :span="8" class="min-w-[100px]">
|
|
||||||
<div class="statistic-card">
|
|
||||||
<el-statistic :value="accountStat.pay ? Number.parseFloat(accountStat.pay).toFixed(2) : '0.00'"></el-statistic>
|
|
||||||
<div class="statistic-footer">
|
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
|
||||||
<span>{{ t('totalPay') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8" class="min-w-[100px]">
|
<el-col :span="8" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="accountStat.refund ? Number.parseFloat(accountStat.refund).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
<div class="statistic-footer">
|
:value="accountStat.pay ? accountStat.pay.toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="statistic-footer">
|
||||||
<span>{{ t('totalRefund') }}</span>
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
</div>
|
<span>{{ t('totalPay') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="8" class="min-w-[100px]">
|
</el-col>
|
||||||
|
<el-col :span="8" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="accountStat.transfer ? Number.parseFloat(accountStat.transfer).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
<div class="statistic-footer">
|
:value="accountStat.refund ? accountStat.refund.toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="statistic-footer">
|
||||||
<span>{{ t('totalTransfer') }}</span>
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
</div>
|
<span>{{ t('totalRefund') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
</el-col>
|
||||||
|
<el-col :span="8" class="min-w-[100px]">
|
||||||
|
<div class="statistic-card">
|
||||||
|
<el-statistic
|
||||||
|
:value="accountStat.transfer ? accountStat.transfer.toFixed(2) : '0.00'"></el-statistic>
|
||||||
|
<div class="statistic-footer">
|
||||||
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
|
<span>{{ t('totalTransfer') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="siteAccountLogTable.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="siteAccountLogTable.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('type')" class="items-center">
|
<el-form-item :label="t('type')" class="items-center">
|
||||||
<el-select v-model="siteAccountLogTable.searchParam.type" class="m-2" :placeholder="t('accountType')" >
|
<el-select v-model="siteAccountLogTable.searchParam.type" class="m-2"
|
||||||
<el-option
|
:placeholder="t('accountType')">
|
||||||
v-for="(item, index) in accountType"
|
<el-option v-for="(item, index) in accountType" :key="index" :label="item" :value="index" />
|
||||||
:key="index"
|
|
||||||
:label="item"
|
|
||||||
:value="index"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('tradeNo')" prop="trade_no">
|
<el-form-item :label="t('tradeNo')" prop="trade_no">
|
||||||
<el-input v-model="siteAccountLogTable.searchParam.trade_no" :placeholder="t('tradeNoPlaceholder')" />
|
<el-input v-model="siteAccountLogTable.searchParam.trade_no"
|
||||||
</el-form-item>
|
:placeholder="t('tradeNoPlaceholder')" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" prop="create_time">
|
<el-form-item :label="t('createTime')" prop="create_time">
|
||||||
<el-date-picker v-model="siteAccountLogTable.searchParam.create_time" type="datetimerange"
|
<el-date-picker v-model="siteAccountLogTable.searchParam.create_time" type="datetimerange"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
:end-placeholder="t('endDate')" />
|
:end-placeholder="t('endDate')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadSiteAccountLogList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadSiteAccountLogList()">{{ t('search') }}</el-button>
|
||||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<div class="mt-[10px]">
|
<div class="mt-[10px]">
|
||||||
<el-table :data="siteAccountLogTable.data" size="large" v-loading="siteAccountLogTable.loading">
|
<el-table :data="siteAccountLogTable.data" size="large" v-loading="siteAccountLogTable.loading">
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !siteAccountLogTable.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !siteAccountLogTable.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column prop="trade_no" :label="t('tradeNo')" min-width="120" />
|
<el-table-column prop="trade_no" :label="t('tradeNo')" min-width="120" />
|
||||||
<el-table-column prop= "type_name" :label="t('type')" min-width="120" />
|
<el-table-column prop="type_name" :label="t('type')" min-width="120" />
|
||||||
<el-table-column prop="money" :label="t('money')" min-width="120" align="right" />
|
<el-table-column prop="money" :label="t('money')" min-width="120" align="right" />
|
||||||
<el-table-column :label="t('createTime')" min-width="150" align="center">
|
<el-table-column :label="t('createTime')" min-width="150" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.create_time || '' }}
|
{{ row.create_time || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" min-width="120">
|
<el-table-column :label="t('operation')" align="right" fixed="right" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</el-button>
|
<el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</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="siteAccountLogTable.page" v-model:page-size="siteAccountLogTable.limit"
|
<el-pagination v-model:current-page="siteAccountLogTable.page"
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="siteAccountLogTable.total"
|
v-model:page-size="siteAccountLogTable.limit" layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="loadSiteAccountLogList()" @current-change="loadSiteAccountLogList" />
|
:total="siteAccountLogTable.total" @size-change="loadSiteAccountLogList()"
|
||||||
</div>
|
@current-change="loadSiteAccountLogList" />
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</div>
|
||||||
|
</el-card>
|
||||||
<el-dialog v-model="showDialog" :title="t('accountDetail')" width="550px" :destroy-on-close="true">
|
<el-dialog v-model="showDialog" :title="t('accountDetail')" width="550px" :destroy-on-close="true">
|
||||||
<el-form :model="formData" label-width="110px" ref="formRef" class="page-form">
|
<el-form :model="formData" label-width="110px" ref="formRef" class="page-form">
|
||||||
|
|
||||||
<el-form-item :label="t('tradeNo')" >
|
<el-form-item :label="t('tradeNo')">
|
||||||
<div class="input-width"> {{ formData.trade_no }} </div>
|
<div class="input-width"> {{ formData.trade_no }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('type')" >
|
<el-form-item :label="t('type')">
|
||||||
<div class="input-width"> {{ formData.type_name }} </div>
|
<div class="input-width"> {{ formData.type_name }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('money')" >
|
<el-form-item :label="t('money')">
|
||||||
<div class="input-width"> {{ formData.money }} </div>
|
<div class="input-width"> {{ formData.money }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" >
|
<el-form-item :label="t('createTime')">
|
||||||
<div class="input-width"> {{ formData.create_time }} </div>
|
<div class="input-width"> {{ formData.create_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="formData.type == 'transfer'">
|
<div v-if="formData.type == 'transfer'">
|
||||||
<el-form-item :label="t('transferNo')" >
|
<el-form-item :label="t('transferNo')">
|
||||||
<div class="input-width"> {{ formData.pay_info.transfer_no }} </div>
|
<div class="input-width"> {{ formData.pay_info.transfer_no }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('transferTime')" >
|
<el-form-item :label="t('transferTime')">
|
||||||
<div class="input-width"> {{ formData.pay_info.transfer_time }} </div>
|
<div class="input-width"> {{ formData.pay_info.transfer_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('transferType')" >
|
<el-form-item :label="t('transferType')">
|
||||||
<div class="input-width"> {{ formData.pay_info.transfer_type }} </div>
|
<div class="input-width"> {{ formData.pay_info.transfer_type }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('transferMoney')" >
|
<el-form-item :label="t('transferMoney')">
|
||||||
<div class="input-width"> {{ formData.pay_info.money }} </div>
|
<div class="input-width"> {{ formData.pay_info.money }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('transferRemark')" >
|
<el-form-item :label="t('transferRemark')">
|
||||||
<div class="input-width"> {{ formData.pay_info.remark }} </div>
|
<div class="input-width"> {{ formData.pay_info.remark }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="formData.type == 'refund'">
|
<div v-if="formData.type == 'refund'">
|
||||||
<el-form-item :label="t('outTradeNo')" >
|
<el-form-item :label="t('outTradeNo')">
|
||||||
<div class="input-width"> {{ formData.pay_info.out_trade_no }} </div>
|
<div class="input-width"> {{ formData.pay_info.out_trade_no }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" >
|
<el-form-item :label="t('createTime')">
|
||||||
<div class="input-width"> {{ formData.pay_info.create_time }} </div>
|
<div class="input-width"> {{ formData.pay_info.create_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('refundMoney')" >
|
<el-form-item :label="t('refundMoney')">
|
||||||
<div class="input-width"> {{ formData.pay_info.money }} </div>
|
<div class="input-width"> {{ formData.pay_info.money }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('failReason')" >
|
<el-form-item :label="t('failReason')">
|
||||||
<div class="input-width"> {{ formData.pay_info.fail_reason }} </div>
|
<div class="input-width"> {{ formData.pay_info.fail_reason }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="formData.type == 'pay'">
|
<div v-if="formData.type == 'pay'">
|
||||||
<el-form-item :label="t('outTradeNo')" >
|
<el-form-item :label="t('outTradeNo')">
|
||||||
<div class="input-width"> {{ formData.pay_info.out_trade_no }} </div>
|
<div class="input-width"> {{ formData.pay_info.out_trade_no }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" >
|
<el-form-item :label="t('createTime')">
|
||||||
<div class="input-width"> {{ formData.pay_info.create_time }} </div>
|
<div class="input-width"> {{ formData.pay_info.create_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('money')" >
|
<el-form-item :label="t('money')">
|
||||||
<div class="input-width"> {{ formData.pay_info.money }} </div>
|
<div class="input-width"> {{ formData.pay_info.money }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('body')" >
|
<el-form-item :label="t('body')">
|
||||||
<div class="input-width"> {{ formData.pay_info.body }} </div>
|
<div class="input-width"> {{ formData.pay_info.body }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-form-item :label="t('headimg')" >
|
|
||||||
<div class="flex items-center">
|
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="formData.member.headimg" :src="img(formData.member.headimg)" alt="" >
|
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item :label="t('memberId')" >
|
</el-form>
|
||||||
<div class="input-width"> {{ formData.member.member_no }} </div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item :label="t('nickName')" >
|
<template #footer>
|
||||||
<div class="input-width"> {{ formData.member.nickname }} </div>
|
<span class="dialog-footer">
|
||||||
</el-form-item>
|
<el-button type="primary" @click="showDialog = false">{{ t('confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<el-form-item :label="t('mobile')" >
|
|
||||||
<div class="input-width"> {{ formData.member.mobile }} </div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item :label="t('accountData')" >
|
|
||||||
<div class="input-width"> {{ formData.account_data }} </div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item :label="t('fromType')" >
|
|
||||||
<div class="input-width"> {{ formData.from_type_name }} </div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item :label="t('memo')" >
|
|
||||||
<div class="input-width"> {{ formData.memo }} </div>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item :label="t('createTime')" >
|
|
||||||
<div class="input-width"> {{ formData.create_time }} </div>
|
|
||||||
</el-form-item> -->
|
|
||||||
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="showDialog = false">{{ t('confirm') }}</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getAccountList, getAccountStat, getAccountType } from '@/app/api/site'
|
import { getAccountList, getAccountStat, getAccountType } from '@/app/api/site'
|
||||||
import { img } from '@/utils/common'
|
// import { img } from '@/utils/common'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let siteAccountLogTable = reactive({
|
const siteAccountLogTable = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
site_id: "",
|
site_id: '',
|
||||||
type: "",
|
type: '',
|
||||||
money: "",
|
money: '',
|
||||||
trade_no: "",
|
trade_no: '',
|
||||||
create_time: ""
|
create_time: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -240,7 +206,7 @@ const loadSiteAccountLogList = (page: number = 1) => {
|
|||||||
getAccountList({
|
getAccountList({
|
||||||
page: siteAccountLogTable.page,
|
page: siteAccountLogTable.page,
|
||||||
limit: siteAccountLogTable.limit,
|
limit: siteAccountLogTable.limit,
|
||||||
...siteAccountLogTable.searchParam
|
...siteAccountLogTable.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
siteAccountLogTable.loading = false
|
siteAccountLogTable.loading = false
|
||||||
siteAccountLogTable.data = res.data.data
|
siteAccountLogTable.data = res.data.data
|
||||||
@ -251,8 +217,6 @@ const loadSiteAccountLogList = (page: number = 1) => {
|
|||||||
}
|
}
|
||||||
loadSiteAccountLogList()
|
loadSiteAccountLogList()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields()
|
formEl.resetFields()
|
||||||
@ -261,19 +225,46 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
|||||||
|
|
||||||
const accountType = ref([])
|
const accountType = ref([])
|
||||||
const checkAccountType = () => {
|
const checkAccountType = () => {
|
||||||
getAccountType().then(res=>{
|
getAccountType().then(res => {
|
||||||
accountType.value = res.data
|
accountType.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkAccountType()
|
checkAccountType()
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const formData = ref([]);
|
const formData = ref({
|
||||||
const detailEvent = (info) => {
|
trade_no: '',
|
||||||
showDialog.value = true
|
type_name: '',
|
||||||
formData.value = info
|
money: 0,
|
||||||
|
create_time: '',
|
||||||
|
type: '',
|
||||||
|
pay_info: {
|
||||||
|
transfer_no: '',
|
||||||
|
transfer_time: '',
|
||||||
|
transfer_type: '',
|
||||||
|
money: 0,
|
||||||
|
remark: '',
|
||||||
|
out_trade_no: '',
|
||||||
|
create_time: '',
|
||||||
|
fail_reason: '',
|
||||||
|
body: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const detailEvent = (info:any) => {
|
||||||
|
showDialog.value = true
|
||||||
|
formData.value = info
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountStat = ref([])
|
interface AccountStat{
|
||||||
|
pay: number,
|
||||||
|
refund: number,
|
||||||
|
transfer: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountStat = ref<AccountStat>({
|
||||||
|
pay: 0,
|
||||||
|
refund: 0,
|
||||||
|
transfer: 0
|
||||||
|
})
|
||||||
const checkAccountStat = async () => {
|
const checkAccountStat = async () => {
|
||||||
accountStat.value = await (await getAccountStat()).data
|
accountStat.value = await (await getAccountStat()).data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,32 +2,34 @@
|
|||||||
<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 justify-between items-center mb-[5px]">
|
<div class="flex justify-between items-center mb-[5px]">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
||||||
<el-row class="flex">
|
<el-row class="flex">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="statistics.transfered ? Number.parseFloat(statistics.transfered).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="statistics.transfered ? statistics.transfered.toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('totalTransfered') }}</span>
|
<span>{{ t('totalTransfered') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="statistics.cash_outing ? Number.parseFloat(statistics.cash_outing).toFixed(2) : '0'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="statistics.cash_outing ? statistics.cash_outing.toFixed(2) : '0'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('totalCashOuting') }}</span>
|
<span>{{ t('totalCashOuting') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
||||||
@ -36,39 +38,39 @@
|
|||||||
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
:end-placeholder="t('endDate')" />
|
:end-placeholder="t('endDate')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('cashOutNumber')" prop="cash_out_no">
|
<el-form-item :label="t('cashOutNumber')" prop="cash_out_no">
|
||||||
<el-input v-model="orderTableData.searchParam.cash_out_no" class="w-[240px]"
|
<el-input v-model="orderTableData.searchParam.cash_out_no" class="w-[240px]"
|
||||||
:placeholder="t('cashOutNumberPlaceholder')" />
|
:placeholder="t('cashOutNumberPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memberInfo')" prop="keyword">
|
<el-form-item :label="t('memberInfo')" prop="keyword">
|
||||||
<el-input v-model="orderTableData.searchParam.keyword" class="w-[240px]"
|
<el-input v-model="orderTableData.searchParam.keyword" class="w-[240px]"
|
||||||
:placeholder="t('memberInfoPlaceholder')" />
|
:placeholder="t('memberInfoPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('cashOutMethod')" prop="transfer_type">
|
<el-form-item :label="t('cashOutMethod')" prop="transfer_type">
|
||||||
<el-select v-model="orderTableData.searchParam.transfer_type" clearable class="input-width">
|
<el-select v-model="orderTableData.searchParam.transfer_type" clearable class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item.name" :value="key" v-for="(item, key) in Transfertype" />
|
<el-option :label="item.name" :value="key" v-for="(item, key) in Transfertype" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('cashOutStatus')" prop="order_from">
|
<el-form-item :label="t('cashOutStatus')" prop="order_from">
|
||||||
<el-select v-model="orderTableData.searchParam.status" clearable class="input-width">
|
<el-select v-model="orderTableData.searchParam.status" clearable class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item" :value="key" v-for="(item, key) in cashOutStatusList" />
|
<el-option :label="item" :value="key" v-for="(item, key) in cashOutStatusList" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('auditTime')" prop="audit_time">
|
<el-form-item :label="t('auditTime')" prop="audit_time">
|
||||||
<el-date-picker v-model="orderTableData.searchParam.audit_time" type="datetimerange"
|
<el-date-picker v-model="orderTableData.searchParam.audit_time" type="datetimerange"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
:end-placeholder="t('endDate')" />
|
:end-placeholder="t('endDate')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('transferTime')" prop="transfer_time">
|
<el-form-item :label="t('transferTime')" prop="transfer_time">
|
||||||
<el-date-picker v-model="orderTableData.searchParam.transfer_time" type="datetimerange"
|
<el-date-picker v-model="orderTableData.searchParam.transfer_time" type="datetimerange"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
:end-placeholder="t('endDate')" />
|
:end-placeholder="t('endDate')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadOrderList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadOrderList()">{{ t('search') }}</el-button>
|
||||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||||
@ -82,11 +84,14 @@
|
|||||||
<span>{{ !orderTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !orderTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table-column prop="order_no" :show-overflow-tooltip="true" :label="t('memberInfo')" align="center" min-width="140">
|
<el-table-column prop="order_no" :show-overflow-tooltip="true" :label="t('memberInfo')" align="center"
|
||||||
|
min-width="140">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center cursor-pointer " @click="toMember(row.member.member_id)">
|
<div class="flex items-center cursor-pointer " @click="toMember(row.member.member_id)">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="" >
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg"
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
:src="img(row.member.headimg)" alt="">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else
|
||||||
|
src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
<div class="flex flex flex-col">
|
<div class="flex flex flex-col">
|
||||||
<span class="">{{ row.member.nickname || '' }}</span>
|
<span class="">{{ row.member.nickname || '' }}</span>
|
||||||
<span class="">{{ row.member.mobile || '' }}</span>
|
<span class="">{{ row.member.mobile || '' }}</span>
|
||||||
@ -94,15 +99,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('cashOutMethod')" align="center" min-width="140" >
|
<el-table-column :label="t('cashOutMethod')" align="center" min-width="140">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ Transfertype[row.transfer_type].name }}
|
{{ Transfertype[row.transfer_type].name }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="apply_money" :label="t('applicationForWithdrawalAmount')" min-width="140" align="center" />
|
<el-table-column prop="apply_money" :label="t('applicationForWithdrawalAmount')" min-width="140"
|
||||||
|
align="center" />
|
||||||
|
|
||||||
<el-table-column prop="money" :label="t('actualTransferAmount')" min-width="200" align="center"/>
|
<el-table-column prop="money" :label="t('actualTransferAmount')" min-width="200" align="center" />
|
||||||
|
|
||||||
<el-table-column prop="service_money" :label="t('cashOutCommission')" align="center" min-width="140" />
|
<el-table-column prop="service_money" :label="t('cashOutCommission')" align="center" min-width="140" />
|
||||||
|
|
||||||
@ -114,21 +120,23 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column :label="t('auditTime')" min-width="180" align="center">
|
<el-table-column :label="t('auditTime')" min-width="180" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.audit_time || '' }}
|
{{ row.audit_time || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column :label="t('transferTime')" min-width="180" align="center">
|
<el-table-column :label="t('transferTime')" min-width="180" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.transfer_time || '' }}
|
{{ row.transfer_time || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="230">
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="230">
|
||||||
<template #default="{ row }">
|
<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>
|
<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>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@ -144,7 +152,8 @@
|
|||||||
|
|
||||||
<!-- 详情 -->
|
<!-- 详情 -->
|
||||||
<el-dialog v-model="cashOutShowDialog" :title="t('cashOutDetail')" width="500px" :destroy-on-close="true">
|
<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 :model="cashOutInfo" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
|
v-loading="cashOutLoading">
|
||||||
<el-form-item :label="t('nickname')">
|
<el-form-item :label="t('nickname')">
|
||||||
<div class="input-width"> {{ cashOutInfo.nickname }} </div>
|
<div class="input-width"> {{ cashOutInfo.nickname }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -169,33 +178,35 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="cashOutShowDialog = false">{{t('confirm')}}</el-button>
|
<el-button type="primary" @click="cashOutShowDialog = false">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 是否审核 -->
|
<!-- 是否审核 -->
|
||||||
<el-dialog v-model="auditShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
|
<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 :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-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-input v-model="auditFailure.refuse_reason" clearable :placeholder="t('reasonsRefusalPlaceholder')"
|
||||||
|
class="input-width" type="textarea" />
|
||||||
</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="auditShowDialog = false">{{ t('cancel') }}</el-button>
|
<el-button @click="auditShowDialog = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{t('confirm')}}</el-button>
|
<el-button type="primary" :loading="loading" @click="confirm()">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 是否转账 -->
|
<!-- 是否转账 -->
|
||||||
<el-dialog v-model="transferShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
|
<el-dialog v-model="transferShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
|
||||||
<p>{{t('isTransfer')}}</p>
|
<p>{{ t('isTransfer') }}</p>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="transferShowDialog = false">{{ t('cancel') }}</el-button>
|
<el-button @click="transferShowDialog = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="confirm(formRef)">{{t('confirm')}}</el-button>
|
<el-button type="primary" @click="confirm()">{{ t('confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -205,44 +216,46 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getCashOutList, getTransfertype, memberTransfer, memberAudit, getCashOutDetail, getCashOutStatusList,getCashOutStat } from '@/app/api/member'
|
import { getCashOutList, getTransfertype, memberTransfer, memberAudit, getCashOutDetail, getCashOutStatusList, getCashOutStat } from '@/app/api/member'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessageBox, FormInstance, FormRules } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
|
||||||
const cashOutStatusList = ref([])
|
const cashOutStatusList = ref([])
|
||||||
const checkStatusList = async () => {
|
const checkStatusList = async () => {
|
||||||
cashOutStatusList.value = await (await getCashOutStatusList({})).data
|
cashOutStatusList.value = await (await getCashOutStatusList()).data
|
||||||
}
|
}
|
||||||
checkStatusList()
|
checkStatusList()
|
||||||
|
const transferShowDialog = ref(false)
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
const member_id: number = parseInt(route.query.id || 0)
|
const operationBtn = ref<AnyObject>({
|
||||||
const operationBtn = ref({
|
1: {
|
||||||
"1": {
|
value: [t('successfulAudit'), t('auditFailure'), t('detail')],
|
||||||
value: [t('successfulAudit'),t('auditFailure'),t('detail')],
|
clickArr: ['successfulAuditFn', 'auditFailureFn', 'detailFn']
|
||||||
clickArr: ['successfulAuditFn','auditFailureFn','detailFn']
|
|
||||||
},
|
},
|
||||||
"2": {
|
2: {
|
||||||
value: [t('transfer'),t('detail')],
|
value: [t('transfer'), t('detail')],
|
||||||
clickArr: ['transferFn','detailFn']
|
clickArr: ['transferFn', 'detailFn']
|
||||||
},
|
},
|
||||||
"3": {
|
3: {
|
||||||
value: [t('detail')],
|
value: [t('detail')],
|
||||||
clickArr: ['detailFn']
|
clickArr: ['detailFn']
|
||||||
},
|
},
|
||||||
"-1": {
|
'-1': {
|
||||||
value: [t('detail')],
|
value: [t('detail')],
|
||||||
clickArr: ['detailFn']
|
clickArr: ['detailFn']
|
||||||
},
|
},
|
||||||
"-2": {
|
'-2': {
|
||||||
value: [t('detail')],
|
value: [t('detail')],
|
||||||
clickArr: ['detailFn']
|
clickArr: ['detailFn']
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const formRules = reactive<FormRules>({})
|
||||||
|
|
||||||
const orderTableData = reactive({
|
const orderTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
@ -252,40 +265,41 @@ const orderTableData = reactive({
|
|||||||
data: [],
|
data: [],
|
||||||
searchParam: {
|
searchParam: {
|
||||||
order_no: '',
|
order_no: '',
|
||||||
member_id,
|
member_id: 0,
|
||||||
create_time: [],
|
create_time: [],
|
||||||
status: '',
|
status: '',
|
||||||
cash_out_no: '',
|
cash_out_no: '',
|
||||||
keyword: '',
|
keyword: '',
|
||||||
audit_time: '',
|
audit_time: '',
|
||||||
transfer_time: '',
|
transfer_time: '',
|
||||||
transfer_type: ''
|
transfer_type: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const statistics = ref([])
|
const statistics = ref({
|
||||||
|
transfered: 0,
|
||||||
|
cash_outing: 0
|
||||||
|
})
|
||||||
const checkStatInfo = () => {
|
const checkStatInfo = () => {
|
||||||
getCashOutStat().then(res => {
|
getCashOutStat().then(res => {
|
||||||
statistics.value = res.data;
|
statistics.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkStatInfo()
|
checkStatInfo()
|
||||||
|
|
||||||
|
|
||||||
// 获取会员转账方式
|
// 获取会员转账方式
|
||||||
const Transfertype = ref<Array<Object>>([])
|
const Transfertype = ref<Array<Object|any>>([])
|
||||||
const getTransfertypeFn = async()=>{
|
const getTransfertypeFn = async () => {
|
||||||
Transfertype.value = await (await getTransfertype()).data
|
Transfertype.value = await (await getTransfertype()).data
|
||||||
}
|
}
|
||||||
getTransfertypeFn()
|
getTransfertypeFn()
|
||||||
|
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadOrderList();
|
loadOrderList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,38 +324,37 @@ const loadOrderList = (page: number = 1) => {
|
|||||||
loadOrderList()
|
loadOrderList()
|
||||||
|
|
||||||
// 函数总处理
|
// 函数总处理
|
||||||
let auditFailure = ref({refuse_reason:'',id:0,action: 0})
|
const auditFailure = ref({ refuse_reason: '', id: 0, action: 0 })
|
||||||
let auditShowDialog = ref(false);
|
const auditShowDialog = ref(false)
|
||||||
const fnProcessing = (type:string, data: any)=>{
|
const fnProcessing = (type: string, data: any) => {
|
||||||
let obj = {}
|
const obj = {}
|
||||||
if(['successfulAuditFn','auditFailureFn'].includes(type)){
|
if (['successfulAuditFn', 'auditFailureFn'].includes(type)) {
|
||||||
obj.id = data.id;
|
obj.id = data.id
|
||||||
if(type == 'successfulAuditFn'){
|
if (type == 'successfulAuditFn') {
|
||||||
obj.action = 'agree';
|
obj.action = 'agree'
|
||||||
cashOutAuditFn(obj)
|
cashOutAuditFn(obj)
|
||||||
}else{
|
} else {
|
||||||
obj.action = 'refuse';
|
obj.action = 'refuse'
|
||||||
auditFailure.value = Object.assign(auditFailure.value,obj);
|
auditFailure.value = Object.assign(auditFailure.value, obj)
|
||||||
auditShowDialog.value = true;
|
auditShowDialog.value = true
|
||||||
}
|
}
|
||||||
}else if(type == 'transferFn'){
|
} else if (type == 'transferFn') {
|
||||||
obj.id = data.id;
|
obj.id = data.id
|
||||||
ElMessageBox.confirm(`${t('isTransfer')}`,`${t('transfer')}`)
|
ElMessageBox.confirm(`${t('isTransfer')}`, `${t('transfer')}`)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
transferFn(obj);
|
transferFn(obj)
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
detailFn(data.id);
|
detailFn(data.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转账
|
* 转账
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const transferFn = (data)=>{
|
const transferFn = (data:any) => {
|
||||||
memberTransfer({...data}).then(res => {
|
memberTransfer({ ...data }).then(res => {
|
||||||
loadOrderList()
|
loadOrderList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loadOrderList()
|
loadOrderList()
|
||||||
@ -353,14 +366,22 @@ const transferFn = (data)=>{
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let cashOutShowDialog = ref(false);
|
const cashOutShowDialog = ref(false)
|
||||||
let cashOutInfo = ref({});
|
const cashOutInfo = ref({
|
||||||
let cashOutLoading = ref(true);
|
nickname: '',
|
||||||
const detailFn = (id)=>{
|
account_type_name: '',
|
||||||
|
transfer_type: '',
|
||||||
|
apply_money: 0,
|
||||||
|
service_money: 0,
|
||||||
|
money: 0,
|
||||||
|
status_name: ''
|
||||||
|
})
|
||||||
|
const cashOutLoading = ref(true)
|
||||||
|
const detailFn = (id:any) => {
|
||||||
getCashOutDetail(id).then(res => {
|
getCashOutDetail(id).then(res => {
|
||||||
cashOutInfo.value = res.data;
|
cashOutInfo.value = res.data
|
||||||
cashOutShowDialog.value = true;
|
cashOutShowDialog.value = true
|
||||||
cashOutLoading.value = false;
|
cashOutLoading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loadOrderList()
|
loadOrderList()
|
||||||
})
|
})
|
||||||
@ -370,7 +391,7 @@ const detailFn = (id)=>{
|
|||||||
* 提现审核
|
* 提现审核
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const cashOutAuditFn = (data)=>{
|
const cashOutAuditFn = (data:any) => {
|
||||||
memberAudit({
|
memberAudit({
|
||||||
...data
|
...data
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
@ -384,25 +405,16 @@ const cashOutAuditFn = (data)=>{
|
|||||||
* 拒绝审核
|
* 拒绝审核
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const confirm = ()=>{
|
const confirm = () => {
|
||||||
auditShowDialog.value = false;
|
auditShowDialog.value = false
|
||||||
cashOutAuditFn(auditFailure.value);
|
cashOutAuditFn(auditFailure.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单详情
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
const infoEvent = (data: any) => {
|
|
||||||
router.push(`/finance/recharge/detail?order_id=${data.order_id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
*/
|
*/
|
||||||
const toMember = (member_id: number) => {
|
const toMember = (memberId: number) => {
|
||||||
router.push(`/member/detail?id=${member_id}`)
|
router.push(`/member/detail?id=${memberId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -52,11 +52,11 @@
|
|||||||
</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 { getPayRefundPages } from '@/app/api/pay'
|
import { getPayRefundPages } from '@/app/api/pay'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
@ -76,7 +76,7 @@ const payRefundTable = reactive({
|
|||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
// 选中数据
|
// 选中数据
|
||||||
const selectData = ref<any[]>([])
|
// const selectData = ref<any[]>([])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取商品标签列表
|
* 获取商品标签列表
|
||||||
@ -99,7 +99,7 @@ const loadPayRefundList = (page: number = 1) => {
|
|||||||
}
|
}
|
||||||
loadPayRefundList()
|
loadPayRefundList()
|
||||||
|
|
||||||
const infoEvent = (data) => {
|
const infoEvent = (data:any) => {
|
||||||
router.push('/finance/refund/detail?refund_no=' + data.refund_no)
|
router.push('/finance/refund/detail?refund_no=' + data.refund_no)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,54 +8,56 @@
|
|||||||
<span class="adorn">|</span>
|
<span class="adorn">|</span>
|
||||||
<span class="right">{{ pageName }}</span>
|
<span class="right">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none relative" shadow="never" v-if="formData">
|
<el-card class="box-card !border-none relative" shadow="never" v-if="formData">
|
||||||
<div class="flex px-[20px] py-[20px] justify-between">
|
<div class="flex px-[20px] py-[20px] justify-between">
|
||||||
<span>{{ t('refundMoney') }}:<span>¥{{ formData.money }}</span></span>
|
<span>{{ t('refundMoney') }}:<span>¥{{ formData.money }}</span></span>
|
||||||
<span>{{ t('refundNo') }}:<span>{{ formData.refund_no }}</span></span>
|
<span>{{ t('refundNo') }}:<span>{{ formData.refund_no }}</span></span>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="refundList" size="large">
|
<el-table :data="refundList" size="large">
|
||||||
<el-table-column prop="out_trade_no" :label="t('outTradeNo')" min-width="200" />
|
<el-table-column prop="out_trade_no" :label="t('outTradeNo')" min-width="200" />
|
||||||
<el-table-column prop="create_time" :label="t('createTime')" min-width="160" />
|
<el-table-column prop="create_time" :label="t('createTime')" min-width="160" />
|
||||||
<el-table-column prop="refund_type_name" :label="t('refundTypeName')" min-width="120" />
|
<el-table-column prop="refund_type_name" :label="t('refundTypeName')" min-width="120" />
|
||||||
<el-table-column :label="t('refundMoney')" min-width="120">
|
<el-table-column :label="t('refundMoney')" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span>¥{{ row.money }}</span>
|
<span>¥{{ row.money }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="status_name" :label="t('statusName')" min-width="120" />
|
<el-table-column prop="status_name" :label="t('statusName')" min-width="120" />
|
||||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="transferEvent(row)" v-if="row.status == 'wait'">{{ t('transfer') }}</el-button>
|
<el-button type="primary" link @click="transferEvent(row)" v-if="row.status == 'wait'">{{
|
||||||
</template>
|
t('transfer') }}</el-button>
|
||||||
</el-table-column>
|
</template>
|
||||||
</el-table>
|
</el-table-column>
|
||||||
</el-card>
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<el-dialog v-model="transferDialog" :title="title" width="500px" class="diy-dialog-wrap"
|
<el-dialog v-model="transferDialog" :title="title" width="500px" class="diy-dialog-wrap" :destroy-on-close="true">
|
||||||
:destroy-on-close="true">
|
<el-form :model="transfeFormData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
<el-form :model="transfeFormData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
v-loading="loading">
|
||||||
<el-form-item :label="t('transferType')">
|
<el-form-item :label="t('transferType')">
|
||||||
<el-radio-group v-model="transfeFormData.refund_type">
|
<el-radio-group v-model="transfeFormData.refund_type">
|
||||||
<el-radio :label="item.value" v-for="(item, index) in refundTypeData" :key="index">{{ item.name }}</el-radio>
|
<el-radio :label="item.value" v-for="(item, index) in refundTypeData" :key="index">{{ item.name
|
||||||
</el-radio-group>
|
}}</el-radio>
|
||||||
</el-form-item>
|
</el-radio-group>
|
||||||
<el-form-item :label="t('refundMoney')" >
|
</el-form-item>
|
||||||
<span>{{ transfeFormData.refund_money }}</span>
|
<el-form-item :label="t('refundMoney')">
|
||||||
</el-form-item>
|
<span>{{ transfeFormData.refund_money }}</span>
|
||||||
<el-form-item :label="t('voucher')" v-if="transfeFormData.refund_type == 'offline'">
|
</el-form-item>
|
||||||
<upload-image v-model="transfeFormData.voucher" />
|
<el-form-item :label="t('voucher')" v-if="transfeFormData.refund_type == 'offline'">
|
||||||
</el-form-item>
|
<upload-image v-model="transfeFormData.voucher" />
|
||||||
</el-form>
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="transferDialog = false">{{ t('cancel') }}</el-button>
|
<el-button @click="transferDialog = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
|
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
|
||||||
t('confirm')
|
t('confirm')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -64,15 +66,13 @@ import { ref, reactive, computed } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getPayRefundInfo, getRefundType, getRefundTransfer } from '@/app/api/pay'
|
import { getPayRefundInfo, getRefundType, getRefundTransfer } from '@/app/api/pay'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { img, getAppType } from '@/utils/common'
|
import { FormInstance } from 'element-plus'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
const refundNo: string = route.query.refund_no
|
const refundNo: string = route.query.refund_no
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const appType = getAppType()
|
|
||||||
|
|
||||||
const refundList = ref([])
|
const refundList = ref([])
|
||||||
const formData: Record<string, any> | null = ref(null)
|
const formData: Record<string, any> | null = ref(null)
|
||||||
@ -102,7 +102,7 @@ getRefundType().then((data) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const transferDialog = ref(false)
|
const transferDialog = ref(false)
|
||||||
const transferEvent = (data) => {
|
const transferEvent = (data:any) => {
|
||||||
transferDialog.value = true
|
transferDialog.value = true
|
||||||
transfeFormData.refund_no = data.refund_no
|
transfeFormData.refund_no = data.refund_no
|
||||||
transfeFormData.refund_money = data.money
|
transfeFormData.refund_money = data.money
|
||||||
@ -140,7 +140,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
transferDialog.value = false
|
transferDialog.value = false
|
||||||
refundList.value = []
|
refundList.value = []
|
||||||
setFormData(refundNo)
|
setFormData(refundNo)
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
transferDialog.value = false
|
transferDialog.value = false
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,23 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container w-full pt-[64px] bg-white" v-loading="loading">
|
<div class="main-container w-full pt-[64px] bg-white" v-loading="loading">
|
||||||
<div class="flex justify-between items-center h-[32px] mb-4">
|
<div class="flex justify-between items-center h-[32px] mb-4">
|
||||||
<span class="text-[20px]">{{ t('editPersonal') }}</span>
|
<span class="text-[20px]">{{ t('editPersonal') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-form :model="saveInfo" label-width="90px" ref="formRef" :rules="formRules" class="page-form">
|
<el-form :model="saveInfo" label-width="90px" ref="formRef" class="page-form">
|
||||||
<el-form-item :label="t('headImg')">
|
<el-form-item :label="t('headImg')">
|
||||||
<upload-image v-model="saveInfo.head_img" :limit="1" />
|
<upload-image v-model="saveInfo.head_img" :limit="1" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('userName')">
|
<el-form-item :label="t('userName')">
|
||||||
<span>{{saveInfo.username}}</span>
|
<span>{{ saveInfo.username }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('realName')">
|
<el-form-item :label="t('realName')">
|
||||||
<el-input v-model="saveInfo.real_name" :placeholder="t('realNamePlaceholder')" clearable class="input-width" />
|
<el-input v-model="saveInfo.real_name" :placeholder="t('realNamePlaceholder')" clearable
|
||||||
|
class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="flex justify-center mt-[50px]">
|
<div class="flex justify-center mt-[50px]">
|
||||||
<el-button type="primary" @click="submitForm(formRef)">{{ t('save') }}</el-button>
|
<el-button type="primary" @click="submitForm(formRef)">{{ t('save') }}</el-button>
|
||||||
<el-button type="primary" @click="returnFn(formRef)">{{ t('cancel') }}</el-button>
|
<el-button type="primary" @click="returnFn()">{{ t('cancel') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
@ -26,77 +27,83 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance, FormRules, ElNotification } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
import { getUserInfo, setUserInfo } from '@/app/api/personal'
|
||||||
import { getUserInfo,setUserInfo } from '@/app/api/personal'
|
import { useRouter } from 'vue-router'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
// 提交信息
|
// 提交信息
|
||||||
let saveInfo = reactive({
|
const saveInfo: {
|
||||||
head_img: '',
|
head_img: string;
|
||||||
real_name: '',
|
real_name: string;
|
||||||
username: ''
|
username: string;
|
||||||
});
|
} = reactive({
|
||||||
|
head_img: '',
|
||||||
|
real_name: '',
|
||||||
|
username: ''
|
||||||
|
})
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>()
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户信息
|
* 获取用户信息
|
||||||
*/
|
*/
|
||||||
const getUserInfoFn = () => {
|
const getUserInfoFn = () => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
getUserInfo().then(res => {
|
getUserInfo().then(res => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
|
|
||||||
let data = res.data;
|
const data = res.data
|
||||||
saveInfo.head_img = data.head_img;
|
saveInfo.head_img = data.head_img
|
||||||
saveInfo.real_name = data.real_name;
|
saveInfo.real_name = data.real_name
|
||||||
saveInfo.username = data.username;
|
saveInfo.username = data.username
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getUserInfoFn();
|
getUserInfoFn()
|
||||||
|
|
||||||
const submitForm = (formEl: FormInstance | undefined) => {
|
const submitForm = (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
formEl.validate((valid) => {
|
formEl.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
|
|
||||||
setUserInfo(saveInfo).then((res: any) => {
|
setUserInfo(saveInfo).then((res: any) => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
}).catch((err: any) => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
const returnFn = ()=>{
|
const returnFn = () => {
|
||||||
router.push('/user/center')
|
router.push('/user/center')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.personal-body){
|
:deep(.personal-body) {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
.el-form-item__content{
|
|
||||||
.el-input{
|
.el-form-item__content {
|
||||||
|
.el-input {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
.el-form-item__content{
|
|
||||||
|
.el-form-item__content {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.el-button{
|
|
||||||
|
.el-button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.personal-option{
|
|
||||||
|
.personal-option {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
<!-- eslint-disable vue/no-deprecated-v-on-native-modifier -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between items-center py-[24px] pl-[62px] pr-[64px] home-head">
|
<div class="flex justify-between items-center py-[24px] pl-[62px] pr-[64px] home-head">
|
||||||
@ -63,18 +64,38 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, toRefs } from 'vue'
|
import { reactive, ref, toRefs } from 'vue'
|
||||||
import { CollectionTag, Search } from '@element-plus/icons-vue'
|
import { Search } from '@element-plus/icons-vue'
|
||||||
import { getHomeSite } from '@/app/api/home'
|
import { getHomeSite } from '@/app/api/home'
|
||||||
import { getWebConfig } from '@/app/api/sys'
|
import { getWebConfig } from '@/app/api/sys'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import { getInstalledAddonList } from '@/app/api/addon'
|
import { getInstalledAddonList } from '@/app/api/addon'
|
||||||
import { useRouter } from 'vue-router'
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
const userStore:AnyObject = useUserStore()
|
||||||
|
|
||||||
const userStore = useUserStore()
|
interface State{
|
||||||
const router = useRouter()
|
params: {
|
||||||
const state = reactive({
|
keywords: string,
|
||||||
|
page: number,
|
||||||
|
limit: number,
|
||||||
|
app: string,
|
||||||
|
sort: boolean
|
||||||
|
},
|
||||||
|
loading: boolean,
|
||||||
|
tableData: {
|
||||||
|
logo: string,
|
||||||
|
app_name: string,
|
||||||
|
site_name: string,
|
||||||
|
create_time: string,
|
||||||
|
expire_time: string,
|
||||||
|
site_id: number,
|
||||||
|
group_name: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const state:State = reactive({
|
||||||
params: {
|
params: {
|
||||||
keywords: '',
|
keywords: '',
|
||||||
page: 1,
|
page: 1,
|
||||||
@ -99,17 +120,19 @@ const getHomeSiteFn = () => {
|
|||||||
getHomeSiteFn()
|
getHomeSiteFn()
|
||||||
|
|
||||||
// 切换应用
|
// 切换应用
|
||||||
const cutAppFn = (app)=>{
|
const cutAppFn = (app:any) => {
|
||||||
state.params.app = app;
|
state.params.app = app
|
||||||
getHomeSiteFn();
|
getHomeSiteFn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 网络设置
|
// 网络设置
|
||||||
let webConfig = ref({})
|
const webConfig = ref({
|
||||||
const getWebConfigFn = () =>{
|
icon: '',
|
||||||
getWebConfig().then(res =>{
|
site_name: ''
|
||||||
webConfig.value = res.data;
|
})
|
||||||
|
const getWebConfigFn = () => {
|
||||||
|
getWebConfig().then(res => {
|
||||||
|
webConfig.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getWebConfigFn()
|
getWebConfigFn()
|
||||||
@ -128,19 +151,19 @@ const selectSite = (site: any) => {
|
|||||||
})
|
})
|
||||||
location.href = `${location.origin}/site/`
|
location.href = `${location.origin}/site/`
|
||||||
}
|
}
|
||||||
const logoutFn = ()=>{
|
const logoutFn = () => {
|
||||||
userStore.logout();
|
userStore.logout()
|
||||||
}
|
|
||||||
const toLinkFn = (link)=>{
|
|
||||||
router.push(link)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取应用列表
|
* 获取应用列表
|
||||||
*/
|
*/
|
||||||
const addonList = ref([])
|
const addonList = ref<{
|
||||||
|
key: string,
|
||||||
|
title: string
|
||||||
|
}[]>([])
|
||||||
getInstalledAddonList().then(({ data }) => {
|
getInstalledAddonList().then(({ data }) => {
|
||||||
const apps = []
|
const apps:any = []
|
||||||
Object.keys(data).forEach(key => {
|
Object.keys(data).forEach(key => {
|
||||||
const addon = data[key]
|
const addon = data[key]
|
||||||
addon.type == 'app' && apps.push(addon)
|
addon.type == 'app' && apps.push(addon)
|
||||||
@ -149,7 +172,7 @@ getInstalledAddonList().then(({ data }) => {
|
|||||||
}).catch()
|
}).catch()
|
||||||
|
|
||||||
const handleChick = () => {
|
const handleChick = () => {
|
||||||
ElMessage('加班加点研发中...')
|
ElMessage('加班加点研发中...')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container w-full pt-[64px] bg-white" v-loading="loading">
|
<div class="main-container w-full pt-[64px] bg-white" v-loading="loading">
|
||||||
<div class="flex justify-between items-center h-[32px] mb-4">
|
<div class="flex justify-between items-center h-[32px] mb-4">
|
||||||
<span class="text-[20px]">{{ t('personal') }}</span>
|
<span class="text-[20px]">{{ t("personal") }}</span>
|
||||||
<span class="text-[14px] text-[#999] cursor-pointer" @click="toEditPersonal">{{ t('editPersonal') }}</span>
|
<span class="text-[14px] text-[#999] cursor-pointer" @click="toEditPersonal">{{ t("editPersonal") }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-form :model="saveInfo" label-width="90px" ref="formRef" class="page-form">
|
<el-form :model="saveInfo" label-width="90px" ref="formRef" class="page-form">
|
||||||
<el-form-item :label="t('headImg')">
|
<el-form-item :label="t('headImg')">
|
||||||
<el-image class="w-[70px] h-[70px]" :src="img(saveInfo.head_img)" fit="contain">
|
<el-image class="w-[70px] h-[70px]" :src="img(saveInfo.head_img)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot bg-[#c0c4cc] flex items-center justify-center w-[70px] h-[70px] rounded-full">
|
<div
|
||||||
<el-icon class="!text-[#fff] !text-[45px]"><UserFilled /></el-icon>
|
class="image-slot bg-[#c0c4cc] flex items-center justify-center w-[70px] h-[70px] rounded-full">
|
||||||
|
<el-icon class="!text-[#fff] !text-[45px]">
|
||||||
|
<UserFilled />
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('userName')">
|
<el-form-item :label="t('userName')">
|
||||||
<div>{{saveInfo.username}}</div>
|
<div>{{ saveInfo.username }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('realName')">
|
<el-form-item :label="t('realName')">
|
||||||
<div>{{saveInfo.real_name}}</div>
|
<div>{{ saveInfo.real_name }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -29,45 +32,46 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance, FormRules, ElNotification } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getUserInfo,setUserInfo } from '@/app/api/personal'
|
import { getUserInfo } from '@/app/api/personal'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
// 提交信息
|
// 提交信息
|
||||||
let saveInfo = reactive({
|
const saveInfo = reactive({
|
||||||
head_img: '',
|
head_img: '',
|
||||||
real_name: '',
|
real_name: '',
|
||||||
original_password: '',
|
original_password: '',
|
||||||
password: '',
|
password: '',
|
||||||
password_copy: '',
|
password_copy: '',
|
||||||
username: ''
|
username: ''
|
||||||
});
|
})
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>()
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户信息
|
* 获取用户信息
|
||||||
*/
|
*/
|
||||||
const getUserInfoFn = () => {
|
const getUserInfoFn = () => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
getUserInfo().then(res => {
|
getUserInfo().then((res) => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
|
|
||||||
let data = res.data;
|
const data = res.data
|
||||||
saveInfo.head_img = data.head_img;
|
saveInfo.head_img = data.head_img
|
||||||
saveInfo.real_name = data.real_name;
|
saveInfo.real_name = data.real_name
|
||||||
saveInfo.original_password = data.original_password;
|
saveInfo.original_password = data.original_password
|
||||||
saveInfo.password = data.password;
|
saveInfo.password = data.password
|
||||||
saveInfo.password_copy = data.password;
|
saveInfo.password_copy = data.password
|
||||||
saveInfo.username = data.username;
|
saveInfo.username = data.username
|
||||||
}).catch(() => {
|
|
||||||
loading.value = false;
|
|
||||||
})
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
getUserInfoFn();
|
getUserInfoFn()
|
||||||
|
|
||||||
// 编辑个人中心
|
// 编辑个人中心
|
||||||
const toEditPersonal = () => {
|
const toEditPersonal = () => {
|
||||||
@ -76,19 +80,23 @@ const toEditPersonal = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.personal-body){
|
:deep(.personal-body) {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
.el-form-item__content{
|
|
||||||
.el-input{
|
.el-form-item__content {
|
||||||
|
.el-input {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
.el-form-item__content{
|
|
||||||
|
.el-form-item__content {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.el-button{
|
|
||||||
|
.el-button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.personal-option{
|
|
||||||
|
.personal-option {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,20 +56,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, onMounted, computed } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getInstalledAddonList } from '@/app/api/addon'
|
import { getInstalledAddonList } from '@/app/api/addon'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import { findFirstValidRoute } from '@/router/routers'
|
import { findFirstValidRoute } from '@/router/routers'
|
||||||
import { UserFilled } from '@element-plus/icons-vue'
|
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userStore = useUserStore()
|
const userStore:AnyObject = useUserStore()
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const detail = reactive({
|
const detail:{
|
||||||
|
appList: {
|
||||||
|
title: string,
|
||||||
|
desc: string,
|
||||||
|
icon: string
|
||||||
|
}[]
|
||||||
|
} = reactive({
|
||||||
appList: []
|
appList: []
|
||||||
})
|
})
|
||||||
const appLink: any = ref({})
|
const appLink: any = ref({})
|
||||||
@ -82,7 +88,7 @@ const getAuthaddonFn = () => {
|
|||||||
detail.appList.push(item)
|
detail.appList.push(item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
userStore.routers.forEach((item, index) => {
|
userStore.routers.forEach((item:any, index:number) => {
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
item.name = findFirstValidRoute(item.children)
|
item.name = findFirstValidRoute(item.children)
|
||||||
appLink.value[item.meta.app] = findFirstValidRoute(item.children)
|
appLink.value[item.meta.app] = findFirstValidRoute(item.children)
|
||||||
@ -93,7 +99,6 @@ const getAuthaddonFn = () => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,30 +110,14 @@ const itemPath = (data: any) => {
|
|||||||
const appMenuList = userStore.appMenuList
|
const appMenuList = userStore.appMenuList
|
||||||
appMenuList.push(data.key)
|
appMenuList.push(data.key)
|
||||||
userStore.setAppMenuList(appMenuList)
|
userStore.setAppMenuList(appMenuList)
|
||||||
let name: any = appLink.value[data.key]
|
const name: any = appLink.value[data.key]
|
||||||
router.push({ name: name })
|
router.push({ name })
|
||||||
}
|
|
||||||
|
|
||||||
const goAppManage = () => {
|
|
||||||
router.push('/app_manage')
|
|
||||||
}
|
|
||||||
|
|
||||||
const goRouter = () => {
|
|
||||||
window.open('https://www.niucloud.com/app')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转至开发者
|
// 跳转至开发者
|
||||||
const toAppStore = () => {
|
const toAppStore = () => {
|
||||||
router.push('/app_manage/app_store')
|
router.push('/app_manage/app_store')
|
||||||
}
|
}
|
||||||
|
|
||||||
const goNiucloud = () => {
|
|
||||||
window.open('https://www.niucloud.com')
|
|
||||||
}
|
|
||||||
|
|
||||||
const logout = () => {
|
|
||||||
userStore.logout();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<span class="text-[20px]">{{ t('editPersonal') }}</span>
|
<span class="text-[20px]">{{ t('editPersonal') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
<el-form :model="saveInfo" label-width="90px" ref="formRef" :rules="formRules" class="page-form">
|
<el-form :model="saveInfo" label-width="90px" ref="formRef" class="page-form">
|
||||||
<el-form-item :label="t('headImg')">
|
<el-form-item :label="t('headImg')">
|
||||||
<upload-image v-model="saveInfo.head_img" :limit="1" />
|
<upload-image v-model="saveInfo.head_img" :limit="1" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<div class="flex justify-center mt-[50px]">
|
<div class="flex justify-center mt-[50px]">
|
||||||
<el-button type="primary" @click="submitForm(formRef)">{{ t('save') }}</el-button>
|
<el-button type="primary" @click="submitForm(formRef)">{{ t('save') }}</el-button>
|
||||||
<el-button type="primary" @click="returnFn(formRef)">{{ t('cancel') }}</el-button>
|
<el-button type="primary" @click="returnFn()">{{ t('cancel') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
@ -26,57 +26,56 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance, FormRules, ElNotification } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
|
||||||
import { getUserInfo,setUserInfo } from '@/app/api/personal'
|
import { getUserInfo, setUserInfo } from '@/app/api/personal'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
// 提交信息
|
// 提交信息
|
||||||
let saveInfo = reactive({
|
const saveInfo = reactive({
|
||||||
head_img: '',
|
head_img: '',
|
||||||
real_name: '',
|
real_name: '',
|
||||||
username: ''
|
username: ''
|
||||||
});
|
})
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>()
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户信息
|
* 获取用户信息
|
||||||
*/
|
*/
|
||||||
const getUserInfoFn = () => {
|
const getUserInfoFn = () => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
getUserInfo().then(res => {
|
getUserInfo().then(res => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
|
const data = res.data
|
||||||
let data = res.data;
|
saveInfo.head_img = data.head_img
|
||||||
saveInfo.head_img = data.head_img;
|
saveInfo.real_name = data.real_name
|
||||||
saveInfo.real_name = data.real_name;
|
saveInfo.username = data.username
|
||||||
saveInfo.username = data.username;
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getUserInfoFn();
|
getUserInfoFn()
|
||||||
|
|
||||||
const submitForm = (formEl: FormInstance | undefined) => {
|
const submitForm = (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
formEl.validate((valid) => {
|
formEl.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
|
|
||||||
setUserInfo(saveInfo).then((res: any) => {
|
setUserInfo(saveInfo).then((res: any) => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
}).catch((err: any) => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
const returnFn = ()=>{
|
const returnFn = () => {
|
||||||
router.push('/user/center')
|
router.push('/user/center')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
<!-- eslint-disable no-undef -->
|
||||||
<template>
|
<template>
|
||||||
<div class="bg-[#FAFAFA] box-border pb-[77px]">
|
<div class="bg-[#FAFAFA] box-border pb-[77px]">
|
||||||
<div class="main-container" v-loading="loading">
|
<div class="main-container" v-loading="loading">
|
||||||
@ -164,33 +165,43 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, watch } from "vue";
|
import { ref, watch } from 'vue'
|
||||||
import useSystemStore from "@/stores/modules/system";
|
import { t } from '@/lang'
|
||||||
import { t } from "@/lang";
|
import { getStatInfo } from '@/app/api/stat'
|
||||||
import { getStatInfo } from "@/app/api/stat";
|
import * as echarts from 'echarts'
|
||||||
import * as echarts from "echarts";
|
|
||||||
import { img } from "@/utils/common";
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import { useRoute } from "vue-router";
|
|
||||||
import useStyleStore from '@/stores/modules/style'
|
import useStyleStore from '@/stores/modules/style'
|
||||||
import { getFrameworkNewVersion } from '@/app/api/module'
|
import { getFrameworkNewVersion } from '@/app/api/module'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { AnyObject } from '@/types/global'
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
const loading = ref(true);
|
const newSiteStat = ref<any>(null)
|
||||||
const visitStat = ref<any>(null);
|
const siteStat = ref<any>(null)
|
||||||
const memberStat = ref<any>(null);
|
|
||||||
|
|
||||||
const newSiteStat = ref<any>(null);
|
|
||||||
const siteStat = ref<any>(null);
|
|
||||||
|
|
||||||
const systemStore = useSystemStore();
|
|
||||||
const styleStore = useStyleStore()
|
const styleStore = useStyleStore()
|
||||||
const newVersion = ref(null)
|
|
||||||
|
interface NewVersion{
|
||||||
|
last_version: string
|
||||||
|
}
|
||||||
|
interface StatInfo {
|
||||||
|
today_data: AnyObject,
|
||||||
|
system: AnyObject,
|
||||||
|
version: AnyObject,
|
||||||
|
about: any,
|
||||||
|
site_stat: AnyObject,
|
||||||
|
site_group_stat: AnyObject,
|
||||||
|
app: AnyObject
|
||||||
|
}
|
||||||
|
|
||||||
|
const newVersion = ref<NewVersion>({
|
||||||
|
last_version: ''
|
||||||
|
})
|
||||||
|
|
||||||
getFrameworkNewVersion().then(({ data }) => {
|
getFrameworkNewVersion().then(({ data }) => {
|
||||||
newVersion.value = data
|
newVersion.value = data
|
||||||
}).catch()
|
}).catch()
|
||||||
|
|
||||||
let statInfo = ref({
|
const statInfo = ref<StatInfo>({
|
||||||
today_data: {},
|
today_data: {},
|
||||||
system: {},
|
system: {},
|
||||||
version: {},
|
version: {},
|
||||||
@ -198,44 +209,44 @@ let statInfo = ref({
|
|||||||
site_stat: {},
|
site_stat: {},
|
||||||
site_group_stat: {},
|
site_group_stat: {},
|
||||||
app: {}
|
app: {}
|
||||||
});
|
})
|
||||||
const getStatInfoFn = async (id: number = 0) => {
|
const getStatInfoFn = async (id: number = 0) => {
|
||||||
statInfo.value = await (await getStatInfo()).data;
|
statInfo.value = await (await getStatInfo()).data
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
drawChart();
|
drawChart()
|
||||||
}, 20);
|
}, 20)
|
||||||
};
|
}
|
||||||
getStatInfoFn();
|
getStatInfoFn()
|
||||||
|
|
||||||
// 绘制折线图
|
// 绘制折线图
|
||||||
const drawChart = () => {
|
const drawChart = () => {
|
||||||
//新增站点
|
// 新增站点
|
||||||
const newSiteStatChart = echarts.init(newSiteStat.value);
|
const newSiteStatChart = echarts.init(newSiteStat.value)
|
||||||
const newSiteStatOption = ref({
|
const newSiteStatOption = ref({
|
||||||
legend: {},
|
legend: {},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
data: [],
|
data: []
|
||||||
},
|
},
|
||||||
yAxis: {},
|
yAxis: {},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: "axis",
|
trigger: 'axis'
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: t("newSite"),
|
name: t('newSite'),
|
||||||
type: "line",
|
type: 'line',
|
||||||
data: [],
|
data: []
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
});
|
})
|
||||||
newSiteStatOption.value.xAxis.data = statInfo.value.site_stat.date;
|
newSiteStatOption.value.xAxis.data = statInfo.value.site_stat.date
|
||||||
newSiteStatOption.value.series[0].data = statInfo.value.site_stat.value;
|
newSiteStatOption.value.series[0].data = statInfo.value.site_stat.value
|
||||||
newSiteStatChart.setOption(newSiteStatOption.value);
|
newSiteStatChart.setOption(newSiteStatOption.value)
|
||||||
|
|
||||||
// 站点分布
|
// 站点分布
|
||||||
const siteStatChart = echarts.init(siteStat.value);
|
const siteStatChart = echarts.init(siteStat.value)
|
||||||
const siteStatOption = ref({
|
const siteStatOption:AnyObject = ref({
|
||||||
legend: {
|
legend: {
|
||||||
orient: 'vertical',
|
orient: 'vertical',
|
||||||
right: 20,
|
right: 20,
|
||||||
@ -244,34 +255,40 @@ const drawChart = () => {
|
|||||||
tooltip: {},
|
tooltip: {},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
type: "pie",
|
type: 'pie',
|
||||||
data: [],
|
data: []
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
});
|
})
|
||||||
|
|
||||||
const len = statInfo.value.site_group_stat.type.length;
|
const len = statInfo.value.site_group_stat.type.length
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
let obj = {};
|
const obj:{
|
||||||
obj.name = statInfo.value.site_group_stat.type[i];
|
name: string,
|
||||||
obj.value = statInfo.value.site_group_stat.value[i];
|
value: number
|
||||||
siteStatOption.value.series[0].data.push(obj);
|
} = {
|
||||||
|
name: '',
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
obj.name = statInfo.value.site_group_stat.type[i]
|
||||||
|
obj.value = statInfo.value.site_group_stat.value[i]
|
||||||
|
siteStatOption.value.series[0].data.push(obj)
|
||||||
}
|
}
|
||||||
siteStatChart.setOption(siteStatOption.value);
|
siteStatChart.setOption(siteStatOption.value)
|
||||||
window.addEventListener("resize", () => {
|
window.addEventListener('resize', () => {
|
||||||
//页面大小变化后Echarts也更改大小
|
// 页面大小变化后Echarts也更改大小
|
||||||
newSiteStatChart.resize();
|
newSiteStatChart.resize()
|
||||||
siteStatChart.resize();
|
siteStatChart.resize()
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
if(route.path == '/admin/index'){
|
if (route.path == '/admin/index') {
|
||||||
styleStore.changeStyle()
|
styleStore.changeStyle()
|
||||||
}
|
}
|
||||||
watch(() => route.path, (newval, oldval) => {
|
watch(() => route.path, (newval, oldval) => {
|
||||||
if(newval !== '/admin/index'){
|
if (newval !== '/admin/index') {
|
||||||
styleStore.changeBlack()
|
styleStore.changeBlack()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -279,19 +296,19 @@ watch(() => route.path, (newval, oldval) => {
|
|||||||
/**
|
/**
|
||||||
* 链接跳转
|
* 链接跳转
|
||||||
*/
|
*/
|
||||||
const toLink = (link) => {
|
const toLink = (link:any) => {
|
||||||
router.push(link);
|
router.push(link)
|
||||||
};
|
|
||||||
const toHref = (url:any,id:any) =>{
|
|
||||||
router.push({
|
|
||||||
path:url,
|
|
||||||
query:{id}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
const toApplication = ()=>{
|
const toHref = (url:any, id:any) => {
|
||||||
|
router.push({
|
||||||
|
path: url,
|
||||||
|
query: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const toApplication = () => {
|
||||||
window.open('https://www.niucloud.com/app')
|
window.open('https://www.niucloud.com/app')
|
||||||
}
|
}
|
||||||
//更新时间
|
// 更新时间
|
||||||
const time = ref('')
|
const time = ref('')
|
||||||
const nowTime = () => {
|
const nowTime = () => {
|
||||||
const date = new Date()
|
const date = new Date()
|
||||||
@ -301,7 +318,7 @@ const nowTime = () => {
|
|||||||
const hh = checkTime(date.getHours())
|
const hh = checkTime(date.getHours())
|
||||||
const mm = checkTime(date.getMinutes())
|
const mm = checkTime(date.getMinutes())
|
||||||
const ss = checkTime(date.getSeconds())
|
const ss = checkTime(date.getSeconds())
|
||||||
function checkTime (i) {
|
function checkTime (i:any) {
|
||||||
if (i < 10) {
|
if (i < 10) {
|
||||||
return '0' + i
|
return '0' + i
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container w-full pt-[64px] bg-white" v-loading="loading">
|
<div class="main-container w-full pt-[64px] bg-white" v-loading="loading">
|
||||||
<div class="flex justify-between items-center h-[32px] mb-4">
|
<div class="flex justify-between items-center h-[32px] mb-4">
|
||||||
<span class="text-[20px]">{{ t('personal') }}</span>
|
<span class="text-[20px]">{{ t('personal') }}</span>
|
||||||
<span class="text-[14px] text-[#999] cursor-pointer" @click="toEditPersonal">{{ t('editPersonal') }}</span>
|
<span class="text-[14px] text-[#999] cursor-pointer" @click="toEditPersonal">{{ t('editPersonal') }}</span>
|
||||||
@ -9,17 +9,20 @@
|
|||||||
<el-form-item :label="t('headImg')">
|
<el-form-item :label="t('headImg')">
|
||||||
<el-image class="w-[70px] h-[70px]" :src="img(saveInfo.head_img)" fit="contain">
|
<el-image class="w-[70px] h-[70px]" :src="img(saveInfo.head_img)" fit="contain">
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot bg-[#c0c4cc] flex items-center justify-center w-[70px] h-[70px] rounded-full">
|
<div
|
||||||
<el-icon class="!text-[#fff] !text-[45px]"><UserFilled /></el-icon>
|
class="image-slot bg-[#c0c4cc] flex items-center justify-center w-[70px] h-[70px] rounded-full">
|
||||||
|
<el-icon class="!text-[#fff] !text-[45px]">
|
||||||
|
<UserFilled />
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('userName')">
|
<el-form-item :label="t('userName')">
|
||||||
<div>{{saveInfo.username}}</div>
|
<div>{{ saveInfo.username }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('realName')">
|
<el-form-item :label="t('realName')">
|
||||||
<div>{{saveInfo.real_name}}</div>
|
<div>{{ saveInfo.real_name }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -29,45 +32,45 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import type { FormInstance, FormRules, ElNotification } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getUserInfo,setUserInfo } from '@/app/api/personal'
|
import { getUserInfo } from '@/app/api/personal'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
// 提交信息
|
// 提交信息
|
||||||
let saveInfo = reactive({
|
const saveInfo = reactive({
|
||||||
head_img: '',
|
head_img: '',
|
||||||
real_name: '',
|
real_name: '',
|
||||||
original_password: '',
|
original_password: '',
|
||||||
password: '',
|
password: '',
|
||||||
password_copy: '',
|
password_copy: '',
|
||||||
username: ''
|
username: ''
|
||||||
});
|
})
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>()
|
||||||
const loading = ref(true);
|
const loading = ref(true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户信息
|
* 获取用户信息
|
||||||
*/
|
*/
|
||||||
const getUserInfoFn = () => {
|
const getUserInfoFn = () => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
getUserInfo().then(res => {
|
getUserInfo().then(res => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
|
|
||||||
let data = res.data;
|
const data = res.data
|
||||||
saveInfo.head_img = data.head_img;
|
saveInfo.head_img = data.head_img
|
||||||
saveInfo.real_name = data.real_name;
|
saveInfo.real_name = data.real_name
|
||||||
saveInfo.original_password = data.original_password;
|
saveInfo.original_password = data.original_password
|
||||||
saveInfo.password = data.password;
|
saveInfo.password = data.password
|
||||||
saveInfo.password_copy = data.password;
|
saveInfo.password_copy = data.password
|
||||||
saveInfo.username = data.username;
|
saveInfo.username = data.username
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getUserInfoFn();
|
getUserInfoFn()
|
||||||
|
|
||||||
// 编辑个人中心
|
// 编辑个人中心
|
||||||
const toEditPersonal = () => {
|
const toEditPersonal = () => {
|
||||||
@ -76,21 +79,24 @@ const toEditPersonal = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.personal-body){
|
:deep(.personal-body) {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
.el-form-item__content{
|
|
||||||
.el-input{
|
.el-form-item__content {
|
||||||
|
.el-input {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
.el-form-item__content{
|
|
||||||
|
.el-form-item__content {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.el-button{
|
|
||||||
|
.el-button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.personal-option{
|
|
||||||
|
.personal-option {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}</style>
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,215 +1,211 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container w-[375px] mx-auto mt-[20px] mb-[40px] relative">
|
<div class="main-container w-[375px] mx-auto mt-[20px] mb-[40px] relative">
|
||||||
|
|
||||||
<div class="flex full-container">
|
<div class="flex full-container">
|
||||||
<iframe v-show="loadingIframe" class="w-[375px]" :src="wapPreview" frameborder="0"
|
<iframe v-show="loadingIframe" class="w-[375px]" :src="wapPreview" frameborder="0" id="previewIframe"></iframe>
|
||||||
id="previewIframe"></iframe>
|
<div v-show="loadingDev" class="w-[375px] border border-slate-100 bg-body pt-[20px] px-[20px]">
|
||||||
<div v-show="loadingDev" class="w-[375px] border border-slate-100 bg-body pt-[20px] px-[20px]">
|
<div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div>
|
||||||
<div class="font-bold text-xl mb-[40px]">{{t('developTitle')}}</div>
|
<div class="mb-[20px] flex flex-col">
|
||||||
<div class="mb-[20px] flex flex-col">
|
<text class="mb-[10px]">{{ t('wapDomain') }}</text>
|
||||||
<text class="mb-[10px]">{{ t('wapDomain') }}</text>
|
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable />
|
||||||
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable/>
|
</div>
|
||||||
</div>
|
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
|
||||||
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="w-[400px] absolute bg-body top-[10%] -right-[450px]" v-if="loadingIframe">
|
<div class="w-[400px] absolute bg-body top-[10%] -right-[450px]" v-if="loadingIframe">
|
||||||
|
|
||||||
<div class="info-wrap mt-[20px]">
|
<div class="info-wrap mt-[20px]">
|
||||||
|
|
||||||
<div class="px-[20px] pb-[10px] font-bold">{{t('h5')}}</div>
|
<div class="px-[20px] pb-[10px] font-bold">{{ t('h5') }}</div>
|
||||||
<el-form label-width="40px" class="px-[20px]">
|
<el-form label-width="40px" class="px-[20px]">
|
||||||
|
|
||||||
<el-form-item :label="t('link')" v-show="wapPreview">
|
<el-form-item :label="t('link')" v-show="wapPreview">
|
||||||
<el-input readonly :value="wapPreview">
|
<el-input readonly :value="wapPreview">
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button @click="copyEvent(wapPreview)" class="bg-primary copy">{{ t('copy') }}
|
<el-button @click="copyEvent(wapPreview)" class="bg-primary copy">{{ t('copy') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label=" " v-show="wapImage">
|
<el-form-item label=" " v-show="wapImage">
|
||||||
<el-image :src="wapImage"/>
|
<el-image :src="wapImage" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="px-[20px] pb-[10px] font-bold mt-[40px]">{{t('weapp')}}</div>
|
<div class="px-[20px] pb-[10px] font-bold mt-[40px]">{{ t('weapp') }}</div>
|
||||||
<el-form label-width="40px" class="px-[20px]">
|
<el-form label-width="40px" class="px-[20px]">
|
||||||
<el-form-item label=" " v-if="weappConfig.qr_code">
|
<el-form-item label=" " v-if="weappConfig.qr_code">
|
||||||
<el-image class="w-[100px] h-[100px]" :src="img(weappConfig.qr_code)"/>
|
<el-image class="w-[100px] h-[100px]" :src="img(weappConfig.qr_code)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label=" " v-else>
|
<el-form-item label=" " v-else>
|
||||||
<span class="text-gray-400">{{t('weappNotSet')}}</span>
|
<span class="text-gray-400">{{ t('weappNotSet') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref, reactive, watch} from 'vue'
|
import { ref, reactive, watch } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { t } from '@/lang'
|
||||||
import {useRoute} from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import {getWeappConfig} from '@/app/api/weapp'
|
import { getWeappConfig } from '@/app/api/weapp'
|
||||||
import {getUrl} from '@/app/api/sys'
|
import { getUrl } from '@/app/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 QRCode from "qrcode";
|
import QRCode from 'qrcode'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
|
|
||||||
const wapUrl = ref('')
|
const wapUrl = ref('')
|
||||||
const wapDomain = ref('')
|
const wapDomain = ref('')
|
||||||
const wapImage = ref('')
|
const wapImage = ref('')
|
||||||
const wapPreview = ref('')
|
const wapPreview = ref('')
|
||||||
|
|
||||||
const loadingIframe = ref(false) // 加载iframe
|
const loadingIframe = ref(false) // 加载iframe
|
||||||
const loadingDev = ref(false) // 加载开发环境配置
|
const loadingDev = ref(false) // 加载开发环境配置
|
||||||
const timeIframe = ref(0) // iframe打开时间
|
const timeIframe = ref(0) // iframe打开时间
|
||||||
const difference = ref(0) // 检测页面加载差异,小于1000毫秒,则配置wap端域名
|
const difference = ref(0) // 检测页面加载差异,小于1000毫秒,则配置wap端域名
|
||||||
|
|
||||||
var time = new Date().getTime();
|
const route = useRoute()
|
||||||
const route = useRoute();
|
route.query.page = route.query.page || '' // 页面路径
|
||||||
route.query.page = route.query.page || ''; // 页面路径
|
|
||||||
|
|
||||||
getUrl().then((res: any) => {
|
getUrl().then((res: any) => {
|
||||||
wapUrl.value = res.data.wap_url;
|
wapUrl.value = res.data.wap_url
|
||||||
setDomain();
|
setDomain()
|
||||||
|
|
||||||
// 生产模式禁止
|
// 生产模式禁止
|
||||||
if (import.meta.env.MODE == 'production') return;
|
if (import.meta.env.MODE == 'production') return
|
||||||
|
|
||||||
wapDomain.value = res.data.wap_domain;
|
wapDomain.value = res.data.wap_domain
|
||||||
|
|
||||||
// env文件配置过wap域名
|
// env文件配置过wap域名
|
||||||
if (wapDomain.value) {
|
if (wapDomain.value) {
|
||||||
wapUrl.value = wapDomain.value + '/wap';
|
wapUrl.value = wapDomain.value + '/wap'
|
||||||
setDomain();
|
setDomain()
|
||||||
}
|
|
||||||
|
|
||||||
let wap_domain_storage = storage.get('wap_domain');
|
|
||||||
if (wap_domain_storage) {
|
|
||||||
wapUrl.value = wap_domain_storage;
|
|
||||||
setDomain();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
const save = () => {
|
|
||||||
if (wapDomain.value.trim().length == 0) {
|
|
||||||
ElMessage({
|
|
||||||
type: 'warning',
|
|
||||||
message: `${t('wapDomainPlaceholder')}`,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wapUrl.value = wapDomain.value + '/wap';
|
|
||||||
setDomain();
|
|
||||||
storage.set({key: 'wap_domain', data: wapUrl.value});
|
|
||||||
loadingIframe.value = true;
|
|
||||||
loadingDev.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const setDomain = () => {
|
const wap_domain_storage = storage.get('wap_domain')
|
||||||
if (route.query.page) {
|
if (wap_domain_storage) {
|
||||||
wapPreview.value = `${wapUrl.value}${route.query.page}`;
|
wapUrl.value = wap_domain_storage
|
||||||
console.log(wapPreview.value)
|
setDomain()
|
||||||
// errorCorrectionLevel:密度容错率L(低)H(高)
|
|
||||||
QRCode.toDataURL(wapPreview.value, {errorCorrectionLevel: 'L', margin: 0, width: 100}).then(url => {
|
|
||||||
wapImage.value = url
|
|
||||||
})
|
|
||||||
timeIframe.value = new Date().getTime();
|
|
||||||
setTimeout(() => {
|
|
||||||
if (difference.value == 0) initLoad();
|
|
||||||
}, 1000 * 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 监听 uni-app 端 是否加载完成
|
const save = () => {
|
||||||
window.addEventListener('message', (event) => {
|
if (wapDomain.value.trim().length == 0) {
|
||||||
try {
|
ElMessage({
|
||||||
let data = JSON.parse(event.data);
|
type: 'warning',
|
||||||
if (['appOnLaunch', 'appOnReady'].indexOf(data.type) != -1) {
|
message: `${t('wapDomainPlaceholder')}`
|
||||||
loadingDev.value = false;
|
})
|
||||||
loadingIframe.value = true;
|
return
|
||||||
var loadTime = new Date().getTime();
|
|
||||||
difference.value = loadTime - timeIframe.value;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
initLoad();
|
|
||||||
console.log('后台接受数据错误', e)
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
// 将数据发送到uniapp
|
|
||||||
const postMessage = () => {
|
|
||||||
let data = JSON.stringify({
|
|
||||||
type: 'appOnReady',
|
|
||||||
message: '加载完成'
|
|
||||||
});
|
|
||||||
if (window.previewIframe) window.previewIframe.contentWindow.postMessage(data, '*');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始化加载状态
|
|
||||||
const initLoad = () => {
|
|
||||||
loadingDev.value = true;
|
|
||||||
loadingIframe.value = false;
|
|
||||||
wapPreview.value = '';
|
|
||||||
wapImage.value = '';
|
|
||||||
}
|
}
|
||||||
|
wapUrl.value = wapDomain.value + '/wap'
|
||||||
|
setDomain()
|
||||||
|
storage.set({ key: 'wap_domain', data: wapUrl.value })
|
||||||
|
loadingIframe.value = true
|
||||||
|
loadingDev.value = false
|
||||||
|
}
|
||||||
|
|
||||||
const weappConfig = reactive({
|
const setDomain = () => {
|
||||||
qr_code: ''
|
if (route.query.page) {
|
||||||
|
wapPreview.value = `${wapUrl.value}${route.query.page}`
|
||||||
|
console.log(wapPreview.value)
|
||||||
|
// errorCorrectionLevel:密度容错率L(低)H(高)
|
||||||
|
QRCode.toDataURL(wapPreview.value, { errorCorrectionLevel: 'L', margin: 0, width: 100 }).then(url => {
|
||||||
|
wapImage.value = url
|
||||||
|
})
|
||||||
|
timeIframe.value = new Date().getTime()
|
||||||
|
setTimeout(() => {
|
||||||
|
if (difference.value == 0) initLoad()
|
||||||
|
}, 1000 * 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听 uni-app 端 是否加载完成
|
||||||
|
window.addEventListener('message', (event) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data)
|
||||||
|
if (['appOnLaunch', 'appOnReady'].indexOf(data.type) != -1) {
|
||||||
|
loadingDev.value = false
|
||||||
|
loadingIframe.value = true
|
||||||
|
const loadTime = new Date().getTime()
|
||||||
|
difference.value = loadTime - timeIframe.value
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
initLoad()
|
||||||
|
console.log('后台接受数据错误', e)
|
||||||
|
}
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
// 将数据发送到uniapp
|
||||||
|
const postMessage = () => {
|
||||||
|
const data = JSON.stringify({
|
||||||
|
type: 'appOnReady',
|
||||||
|
message: '加载完成'
|
||||||
})
|
})
|
||||||
|
if (window.previewIframe) window.previewIframe.contentWindow.postMessage(data, '*')
|
||||||
|
}
|
||||||
|
|
||||||
// 获取微信配置
|
// 初始化加载状态
|
||||||
getWeappConfig().then((res: any) => {
|
const initLoad = () => {
|
||||||
if (res.code == 1) {
|
loadingDev.value = true
|
||||||
let data = res.data;
|
loadingIframe.value = false
|
||||||
weappConfig.qr_code = data.qr_code;
|
wapPreview.value = ''
|
||||||
}
|
wapImage.value = ''
|
||||||
})
|
}
|
||||||
|
|
||||||
// 复制
|
const weappConfig = reactive({
|
||||||
const {copy, isSupported, copied} = useClipboard()
|
qr_code: ''
|
||||||
const copyEvent = (text: string) => {
|
})
|
||||||
if (!isSupported.value) {
|
|
||||||
ElMessage({
|
// 获取微信配置
|
||||||
message: t('notSupportCopy'),
|
getWeappConfig().then((res: any) => {
|
||||||
type: 'warning'
|
if (res.code == 1) {
|
||||||
})
|
const data = res.data
|
||||||
}
|
weappConfig.qr_code = data.qr_code
|
||||||
copy(text)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
watch(copied, () => {
|
// 复制
|
||||||
if (copied.value) {
|
const { copy, isSupported, copied } = useClipboard()
|
||||||
ElMessage({
|
const copyEvent = (text: string) => {
|
||||||
message: t('copySuccess'),
|
if (!isSupported.value) {
|
||||||
type: 'success'
|
ElMessage({
|
||||||
})
|
message: t('notSupportCopy'),
|
||||||
}
|
type: 'warning'
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
copy(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(copied, () => {
|
||||||
|
if (copied.value) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('copySuccess'),
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
body {
|
body {
|
||||||
background: #edf0f3;
|
background: #edf0f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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 lang="scss" scoped>
|
|
||||||
</style>
|
</style>
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -249,7 +249,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]"
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
v-for="item in installCheckResult.dir.is_readable">
|
v-for="(item,index) in installCheckResult.dir.is_readable" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -266,7 +266,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]"
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
v-for="item in installCheckResult.dir.is_write">
|
v-for="(item,index) in installCheckResult.dir.is_write" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -308,7 +308,7 @@
|
|||||||
<div v-show="installStep == 3" class="h-[50vh] mt-[20px] flex flex-col">
|
<div v-show="installStep == 3" class="h-[50vh] mt-[20px] flex flex-col">
|
||||||
<el-result icon="success" :title="t('addonInstallSuccess')"></el-result>
|
<el-result icon="success" :title="t('addonInstallSuccess')"></el-result>
|
||||||
<!-- 提示信息 -->
|
<!-- 提示信息 -->
|
||||||
<div v-for="item in installAfterTips" class="mb-[10px]">
|
<div v-for="(item,index) in installAfterTips" class="mb-[10px]" :key="index">
|
||||||
<el-alert :title="item" type="error" :closable="false" />
|
<el-alert :title="item" type="error" :closable="false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -333,7 +333,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]"
|
<el-row class="pb-[10px] items pl-[15px]"
|
||||||
v-for="item in uninstallCheckResult.dir.is_readable">
|
v-for="(item,index) in uninstallCheckResult.dir.is_readable" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -349,7 +349,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row class="pb-[10px] items pl-[15px]" v-for="item in uninstallCheckResult.dir.is_write">
|
<el-row class="pb-[10px] items pl-[15px]" v-for="(item,index) in uninstallCheckResult.dir.is_write" :key="index">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span>{{ item.dir }}</span>
|
<span>{{ item.dir }}</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -394,7 +394,6 @@ import { t } from '@/lang'
|
|||||||
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck, cancelInstall } from '@/app/api/addon'
|
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck, cancelInstall } from '@/app/api/addon'
|
||||||
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
|
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
|
||||||
import { ElMessage, ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus'
|
import { ElMessage, ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
|
||||||
import 'vue-web-terminal/lib/theme/dark.css'
|
import 'vue-web-terminal/lib/theme/dark.css'
|
||||||
import { Terminal, TerminalFlash } from 'vue-web-terminal'
|
import { Terminal, TerminalFlash } from 'vue-web-terminal'
|
||||||
import { findFirstValidRoute } from '@/router/routers'
|
import { findFirstValidRoute } from '@/router/routers'
|
||||||
@ -421,7 +420,7 @@ const downEventHintFn = () => {
|
|||||||
downEvent(currDownData.value, true)
|
downEvent(currDownData.value, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeNameTabFn = (data) => {
|
const activeNameTabFn = (data:any) => {
|
||||||
activeName.value = data
|
activeName.value = data
|
||||||
storage.set({ key: 'storeActiveName', data })
|
storage.set({ key: 'storeActiveName', data })
|
||||||
}
|
}
|
||||||
@ -563,7 +562,7 @@ const onExecCmd = (key, command, success, failed, name)=> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeIterator(array: string[]) {
|
function makeIterator(array: string[]) {
|
||||||
var nextIndex = 0
|
let nextIndex = 0
|
||||||
return {
|
return {
|
||||||
next() {
|
next() {
|
||||||
if ((nextIndex + 1) == array.length) {
|
if ((nextIndex + 1) == array.length) {
|
||||||
@ -614,6 +613,7 @@ const getInstallTask = (first: boolean = true) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res.data.error) {
|
if (res.data.error) {
|
||||||
|
ElMessage({ message: '插件安装失败', type: 'error', duration: 5000 })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (res.data.mode == 'cloud') {
|
if (res.data.mode == 'cloud') {
|
||||||
@ -982,6 +982,9 @@ html.dark .table-head-bg {
|
|||||||
height: calc(100vh - 120px);
|
height: calc(100vh - 120px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
:deep(.terminal .t-log-box span) {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -123,28 +123,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {reactive, ref, onMounted, computed} from 'vue'
|
import { ref } from 'vue'
|
||||||
import {t} from '@/lang'
|
import { useRouter } from 'vue-router'
|
||||||
import {getAuthaddon} from '@/app/api/auth'
|
import useSystemStore from '@/stores/modules/system'
|
||||||
import {img} from '@/utils/common'
|
|
||||||
import {useRouter} from 'vue-router'
|
|
||||||
import storage from '@/utils/storage'
|
|
||||||
import {findFirstValidRoute} from '@/router/routers'
|
|
||||||
import {UserFilled} from '@element-plus/icons-vue'
|
|
||||||
import useSystemStore from '@/stores/modules/system'
|
|
||||||
|
|
||||||
const systemStore = useSystemStore()
|
const systemStore = useSystemStore()
|
||||||
systemStore.setHeadMenu('');
|
systemStore.setHeadMenu('')
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
let developerDialogVisible = ref(false)
|
const developerDialogVisible = ref(false)
|
||||||
|
|
||||||
const toLink = (link)=>{
|
const toLink = (link:any) => {
|
||||||
router.push(link)
|
router.push(link)
|
||||||
}
|
}
|
||||||
const goRouter = () => {
|
const goRouter = () => {
|
||||||
window.open('https://www.niucloud.com/app')
|
window.open('https://www.niucloud.com/app')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -129,7 +129,7 @@ if (loginType.value == 'site') {
|
|||||||
|
|
||||||
// 验证码 - start
|
// 验证码 - start
|
||||||
const verifyRef = ref(null)
|
const verifyRef = ref(null)
|
||||||
const success = (params) => {
|
const success = (params:any) => {
|
||||||
loginFn({ captcha_code: params.captchaVerification })
|
loginFn({ captcha_code: params.captchaVerification })
|
||||||
}
|
}
|
||||||
// 验证码 - end
|
// 验证码 - end
|
||||||
@ -178,7 +178,7 @@ const loginFn = (data = {}) => {
|
|||||||
const { query: { redirect } } = route
|
const { query: { redirect } } = route
|
||||||
const path = typeof redirect === 'string' ? redirect : '/'
|
const path = typeof redirect === 'string' ? redirect : '/'
|
||||||
router.push(path)
|
router.push(path)
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,24 @@
|
|||||||
<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">
|
||||||
<div class="flex justify-between items-center mb-[5px]">
|
<div class="flex justify-between items-center mb-[5px]">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
||||||
<el-row class="flex">
|
<el-row class="flex">
|
||||||
<el-col :span="8" class="min-w-[100px]">
|
<el-col :span="8" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="balanceStatistics.money && balanceStatistics.balance ? (Number.parseFloat(balanceStatistics.money)+Number.parseFloat(balanceStatistics.balance)).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="balanceStatistics.money && balanceStatistics.balance ? (Number.parseFloat(balanceStatistics.money) + Number.parseFloat(balanceStatistics.balance)).toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('totalAllBalance') }}</span>
|
<span>{{ t('totalAllBalance') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8" class="min-w-[100px]">
|
<el-col :span="8" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="balanceStatistics.money"></el-statistic>
|
<el-statistic :value="balanceStatistics.money"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
@ -25,9 +26,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8" class="min-w-[100px]">
|
<el-col :span="8" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="balanceStatistics.balance"></el-statistic>
|
<el-statistic :value="balanceStatistics.balance"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
@ -35,37 +36,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
||||||
|
|
||||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||||
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]"
|
||||||
|
:placeholder="t('memberInfoPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('balanceType')" prop="from_type">
|
<el-form-item :label="t('balanceType')" prop="from_type">
|
||||||
<el-select v-model="memberAccountLogTableData.balance_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width" @change="checkAccountType">
|
<el-select v-model="memberAccountLogTableData.balance_type" clearable
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
:placeholder="t('fromTypePlaceholder')" class="input-width" @change="checkAccountType">
|
||||||
<el-option :label="item.name" :value="item.type" v-for="(item,key) in balanceStatus" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
</el-select>
|
<el-option :label="item.name" :value="item.type" v-for="(item, key) in balanceStatus" :key="key"/>
|
||||||
</el-form-item>
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('fromType')" prop="from_type">
|
<el-form-item :label="t('fromType')" prop="from_type">
|
||||||
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">
|
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable
|
||||||
|
:placeholder="t('fromTypePlaceholder')" class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item.name" :value="key" v-for="(item,key) in fromTypeList" />
|
<el-option :label="item.name" :value="key" v-for="(item, key) in fromTypeList" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" prop="create_time">
|
<el-form-item :label="t('createTime')" prop="create_time">
|
||||||
<el-date-picker
|
<el-date-picker v-model="memberAccountLogTableData.searchParam.create_time" type="datetimerange"
|
||||||
v-model="memberAccountLogTableData.searchParam.create_time"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
type="datetimerange"
|
:end-placeholder="t('endDate')" />
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
:start-placeholder="t('startDate')"
|
|
||||||
:end-placeholder="t('endDate')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadMemberAccountLogList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadMemberAccountLogList()">{{ t('search') }}</el-button>
|
||||||
@ -81,48 +81,52 @@
|
|||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !memberAccountLogTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !memberAccountLogTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-table-column prop="member_id" :label="t('memberId')" min-width="80" :show-overflow-tooltip="true">
|
<el-table-column prop="member_id" :label="t('memberId')" min-width="80" :show-overflow-tooltip="true">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.member.member_no }}
|
{{ row.member.member_no }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('memberInfo')" min-width="140" :show-overflow-tooltip="true">
|
<el-table-column :label="t('memberInfo')" min-width="140" :show-overflow-tooltip="true">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="" >
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg"
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
:src="img(row.member.headimg)" alt="">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else
|
||||||
|
src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
<div class="flex flex flex-col">
|
<div class="flex flex flex-col">
|
||||||
<span class="">{{ row.member.nickname || '' }}</span>
|
<span class="">{{ row.member.nickname || '' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="mobile" :label="t('mobile')" min-width="90">
|
<el-table-column prop="mobile" :label="t('mobile')" min-width="90">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.member.mobile || '' }}
|
{{ row.member.mobile || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="account_data" :label="t('accountData')" min-width="70" align="right">
|
<el-table-column prop="account_data" :label="t('accountData')" min-width="70" align="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row.account_data >= 0">+{{ row.account_data }}</span>
|
<span v-if="row.account_data >= 0">+{{ row.account_data }}</span>
|
||||||
<span v-else>{{ row.account_data }}</span>
|
<span v-else>{{ row.account_data }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="account_sum" :label="t('accountSum')" min-width="110" align="right"/>
|
<el-table-column prop="account_sum" :label="t('accountSum')" min-width="110" align="right" />
|
||||||
<el-table-column prop="account_type_name" :label="t('balanceType')" min-width="150" align="center" />
|
<el-table-column prop="account_type_name" :label="t('balanceType')" min-width="150" align="center" />
|
||||||
<el-table-column prop="from_type_name" :label="t('fromType')" min-width="120" align=""/>
|
<el-table-column prop="from_type_name" :label="t('fromType')" min-width="120" align="" />
|
||||||
<el-table-column prop="create_time" :show-overflow-tooltip="true" :label="t('createTime')" min-width="150" />
|
<el-table-column prop="create_time" :show-overflow-tooltip="true" :label="t('createTime')"
|
||||||
|
min-width="150" />
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
||||||
<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>
|
||||||
</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="memberAccountLogTableData.page" v-model:page-size="memberAccountLogTableData.limit"
|
<el-pagination v-model:current-page="memberAccountLogTableData.page"
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="memberAccountLogTableData.total"
|
v-model:page-size="memberAccountLogTableData.limit" layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="loadMemberAccountLogList()" @current-change="loadMemberAccountLogList" />
|
:total="memberAccountLogTableData.total" @size-change="loadMemberAccountLogList()"
|
||||||
|
@current-change="loadMemberAccountLogList" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -134,54 +138,53 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import {
|
import {
|
||||||
getBalanceList,
|
getBalanceList,
|
||||||
getChangeTypeList,
|
getChangeTypeList,
|
||||||
getBalanceSum,
|
getBalanceSum,
|
||||||
getBalanceStatus,
|
getBalanceStatus,
|
||||||
getMoneyList,
|
getMoneyList,
|
||||||
getAccountType,
|
getAccountType
|
||||||
} from '@/app/api/member'
|
} from '@/app/api/member'
|
||||||
import { FormInstance } from 'element-plus'
|
import { FormInstance } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import balanceInfo from '@/app/views/member/components/member-balance-info.vue'
|
import balanceInfo from '@/app/views/member/components/member-balance-info.vue'
|
||||||
import { useRoute,useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const member_id: number = parseInt(route.query.id || 0)
|
const member_id: number = parseInt(route.query.id || 0)
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let memberAccountLogTableData = reactive({
|
const memberAccountLogTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
keywords:"",
|
keywords: '',
|
||||||
from_type:"",
|
from_type: '',
|
||||||
create_time:"",
|
create_time: '',
|
||||||
mobile:"",
|
mobile: '',
|
||||||
member_id,
|
member_id: member_id
|
||||||
|
|
||||||
},
|
},
|
||||||
balance_type: ""
|
balance_type: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
let fromTypeList = ref([])
|
const fromTypeList = ref([])
|
||||||
|
|
||||||
const setFromTypeList = async () => {
|
const setFromTypeList = async () => {
|
||||||
fromTypeList.value = await (await getChangeTypeList('balance')).data
|
fromTypeList.value = await (await getChangeTypeList('balance')).data
|
||||||
}
|
}
|
||||||
|
|
||||||
setFromTypeList();
|
setFromTypeList()
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadMemberAccountLogList();
|
loadMemberAccountLogList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,32 +193,31 @@ const resetForm = (formEl: FormInstance | undefined)=>{
|
|||||||
const loadMemberAccountLogList = (page: number = 1) => {
|
const loadMemberAccountLogList = (page: number = 1) => {
|
||||||
memberAccountLogTableData.loading = true
|
memberAccountLogTableData.loading = true
|
||||||
memberAccountLogTableData.page = page
|
memberAccountLogTableData.page = page
|
||||||
if(memberAccountLogTableData.balance_type == "" || memberAccountLogTableData.balance_type == "balance"){
|
if (memberAccountLogTableData.balance_type == '' || memberAccountLogTableData.balance_type == 'balance') {
|
||||||
getBalanceList({
|
getBalanceList({
|
||||||
page: memberAccountLogTableData.page,
|
page: memberAccountLogTableData.page,
|
||||||
limit: memberAccountLogTableData.limit,
|
limit: memberAccountLogTableData.limit,
|
||||||
...memberAccountLogTableData.searchParam
|
...memberAccountLogTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
memberAccountLogTableData.loading = false
|
memberAccountLogTableData.loading = false
|
||||||
memberAccountLogTableData.data = res.data.data
|
memberAccountLogTableData.data = res.data.data
|
||||||
memberAccountLogTableData.total = res.data.total
|
memberAccountLogTableData.total = res.data.total
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
memberAccountLogTableData.loading = false
|
memberAccountLogTableData.loading = false
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
getMoneyList({
|
getMoneyList({
|
||||||
page: memberAccountLogTableData.page,
|
page: memberAccountLogTableData.page,
|
||||||
limit: memberAccountLogTableData.limit,
|
limit: memberAccountLogTableData.limit,
|
||||||
...memberAccountLogTableData.searchParam
|
...memberAccountLogTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
memberAccountLogTableData.loading = false
|
memberAccountLogTableData.loading = false
|
||||||
memberAccountLogTableData.data = res.data.data
|
memberAccountLogTableData.data = res.data.data
|
||||||
memberAccountLogTableData.total = res.data.total
|
memberAccountLogTableData.total = res.data.total
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
memberAccountLogTableData.loading = false
|
memberAccountLogTableData.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
loadMemberAccountLogList()
|
loadMemberAccountLogList()
|
||||||
|
|
||||||
@ -224,7 +226,7 @@ const balanceDialog: Record<string, any> | null = ref(null)
|
|||||||
* 查看详情
|
* 查看详情
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const infoEvent = (data: any) => {
|
const infoEvent = (data: any) => {
|
||||||
balanceDialog.value.setFormData(data)
|
balanceDialog.value.setFormData(data)
|
||||||
balanceDialog.value.showDialog = true
|
balanceDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
@ -234,7 +236,7 @@ const router = useRouter()
|
|||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
*/
|
*/
|
||||||
const toMember = (member_id:number) => {
|
const toMember = (member_id: number) => {
|
||||||
router.push(`/member/detail?id=${member_id}`)
|
router.push(`/member/detail?id=${member_id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,37 +245,37 @@ const toMember = (member_id:number) => {
|
|||||||
*/
|
*/
|
||||||
const balanceStatistics = ref([])
|
const balanceStatistics = ref([])
|
||||||
const checkBalanceInfo = () => {
|
const checkBalanceInfo = () => {
|
||||||
getBalanceSum({
|
getBalanceSum({
|
||||||
member_id
|
member_id
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
balanceStatistics.value = res.data;
|
balanceStatistics.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkBalanceInfo()
|
checkBalanceInfo()
|
||||||
|
|
||||||
//获取余额类型
|
// 获取余额类型
|
||||||
const balanceStatus = ref([])
|
const balanceStatus = ref([])
|
||||||
const checkBalanceStatus = () => {
|
const checkBalanceStatus = () => {
|
||||||
getBalanceStatus().then(res => {
|
getBalanceStatus().then(res => {
|
||||||
for (var i in res.data) {
|
for (var i in res.data) {
|
||||||
if(i == 'balance' || i == 'money'){
|
if (i == 'balance' || i == 'money') {
|
||||||
balanceStatus.value.push({"name" : res.data[i], "type" : i})
|
balanceStatus.value.push({ 'name': res.data[i], 'type': i })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkBalanceStatus()
|
checkBalanceStatus()
|
||||||
|
|
||||||
const checkAccountType = () => {
|
const checkAccountType = () => {
|
||||||
let account_type = memberAccountLogTableData.balance_type;
|
let account_type = memberAccountLogTableData.balance_type
|
||||||
if(memberAccountLogTableData.balance_type == ""){
|
if (memberAccountLogTableData.balance_type == '') {
|
||||||
account_type = "balance"
|
account_type = 'balance'
|
||||||
}
|
}
|
||||||
getAccountType({
|
getAccountType({
|
||||||
account_type
|
account_type
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
fromTypeList.value = res.data;
|
fromTypeList.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkAccountType()
|
checkAccountType()
|
||||||
|
|
||||||
|
|||||||
@ -2,72 +2,74 @@
|
|||||||
<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 justify-between items-center mb-[5px]">
|
<div class="flex justify-between items-center mb-[5px]">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
||||||
<el-row class="flex">
|
<el-row class="flex">
|
||||||
<el-col :span="6" class="min-w-[100px]">
|
<el-col :span="6" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="commissionStatistics.total_commission ? Number.parseFloat(commissionStatistics.total_commission).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="commissionStatistics.total_commission ? Number.parseFloat(commissionStatistics.total_commission).toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('totalCommission') }}</span>
|
<span>{{ t('totalCommission') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" class="min-w-[100px]">
|
<el-col :span="6" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="commissionStatistics.commission ? Number.parseFloat(commissionStatistics.commission).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="commissionStatistics.commission ? Number.parseFloat(commissionStatistics.commission).toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('commission') }}</span>
|
<span>{{ t('commission') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" class="min-w-[100px]">
|
<el-col :span="6" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="commissionStatistics.withdrawn_commission ? Number.parseFloat(commissionStatistics.withdrawn_commission).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="commissionStatistics.withdrawn_commission ? Number.parseFloat(commissionStatistics.withdrawn_commission).toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('withdrawnCommission') }}</span>
|
<span>{{ t('withdrawnCommission') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" class="min-w-[100px]">
|
<el-col :span="6" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="commissionStatistics.commission_cash_outing ? Number.parseFloat(commissionStatistics.commission_cash_outing).toFixed(2) : '0.00'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="commissionStatistics.commission_cash_outing ? Number.parseFloat(commissionStatistics.commission_cash_outing).toFixed(2) : '0.00'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('cashOutingCommission') }}</span>
|
<span>{{ t('cashOutingCommission') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||||
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]"
|
||||||
|
:placeholder="t('memberInfoPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('fromType')" prop="from_type">
|
<el-form-item :label="t('fromType')" prop="from_type">
|
||||||
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">
|
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable
|
||||||
|
:placeholder="t('fromTypePlaceholder')" class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item.name" :value="key" v-for="(item,key) in fromTypeList" />
|
<el-option :label="item.name" :value="key" v-for="(item, key) in fromTypeList" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" prop="create_time">
|
<el-form-item :label="t('createTime')" prop="create_time">
|
||||||
<el-date-picker
|
<el-date-picker v-model="memberAccountLogTableData.searchParam.create_time" type="datetimerange"
|
||||||
v-model="memberAccountLogTableData.searchParam.create_time"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
type="datetimerange"
|
:end-placeholder="t('endDate')" />
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
:start-placeholder="t('startDate')"
|
|
||||||
:end-placeholder="t('endDate')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadMemberAccountLogList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadMemberAccountLogList()">{{ t('search') }}</el-button>
|
||||||
@ -89,45 +91,49 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column :label="t('memberInfo')" min-width="150" :show-overflow-tooltip="true">
|
<el-table-column :label="t('memberInfo')" min-width="150" :show-overflow-tooltip="true">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="" >
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg"
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
:src="img(row.member.headimg)" alt="">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else
|
||||||
|
src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
<div class="flex flex flex-col">
|
<div class="flex flex flex-col">
|
||||||
<span class="">{{ row.member.nickname || '' }}</span>
|
<span class="">{{ row.member.nickname || '' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="mobile" :label="t('mobile')" min-width="100">
|
<el-table-column prop="mobile" :label="t('mobile')" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.member.mobile || '' }}
|
{{ row.member.mobile || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="account_data" :label="t('accountData')" min-width="80" align="right">
|
<el-table-column prop="account_data" :label="t('accountData')" min-width="80" align="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row.account_data >= 0">+{{ row.account_data }}</span>
|
<span v-if="row.account_data >= 0">+{{ row.account_data }}</span>
|
||||||
<span v-else>{{ row.account_data }}</span>
|
<span v-else>{{ row.account_data }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="account_sum" :label="t('accountSum')" min-width="120" align="right"/>
|
<el-table-column prop="account_sum" :label="t('accountSum')" min-width="120" align="right" />
|
||||||
<el-table-column prop="from_type_name" :label="t('fromType')" min-width="180" align="center"/>
|
<el-table-column prop="from_type_name" :label="t('fromType')" min-width="180" align="center" />
|
||||||
<el-table-column prop="create_time" :show-overflow-tooltip="true" :label="t('createTime')" min-width="150" />
|
<el-table-column prop="create_time" :show-overflow-tooltip="true" :label="t('createTime')"
|
||||||
|
min-width="150" />
|
||||||
|
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
||||||
<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>
|
||||||
</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="memberAccountLogTableData.page" v-model:page-size="memberAccountLogTableData.limit"
|
<el-pagination v-model:current-page="memberAccountLogTableData.page"
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="memberAccountLogTableData.total"
|
v-model:page-size="memberAccountLogTableData.limit" layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="loadMemberAccountLogList()" @current-change="loadMemberAccountLogList" />
|
:total="memberAccountLogTableData.total" @size-change="loadMemberAccountLogList()"
|
||||||
|
@current-change="loadMemberAccountLogList" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -139,58 +145,57 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { FormInstance } from 'element-plus'
|
import { FormInstance } from 'element-plus'
|
||||||
import { getChangeTypeList,getCommissionList,getCommissionSum } from '@/app/api/member'
|
import { getChangeTypeList, getCommissionList, getCommissionSum } from '@/app/api/member'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import moneyInfo from '@/app/views/member/components/member-commission-info.vue'
|
import moneyInfo from '@/app/views/member/components/member-commission-info.vue'
|
||||||
import { useRouter,useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const member_id: number = parseInt(route.query.id || 0)
|
const member_id: number = parseInt(route.query.id || 0)
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let memberAccountLogTableData = reactive({
|
const memberAccountLogTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
keywords:"",
|
keywords: '',
|
||||||
from_type:"",
|
from_type: '',
|
||||||
create_time:"",
|
create_time: '',
|
||||||
mobile:"",
|
mobile: '',
|
||||||
member_id:member_id
|
member_id: member_id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const fromTypeList = ref([])
|
||||||
let fromTypeList = ref([])
|
|
||||||
|
|
||||||
const setFromTypeList = async () => {
|
const setFromTypeList = async () => {
|
||||||
fromTypeList.value = await (await getChangeTypeList('commission')).data
|
fromTypeList.value = await (await getChangeTypeList('commission')).data
|
||||||
}
|
}
|
||||||
|
|
||||||
setFromTypeList();
|
setFromTypeList()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取佣金总计
|
* 获取佣金总计
|
||||||
*/
|
*/
|
||||||
const commissionStatistics = ref([])
|
const commissionStatistics = ref([])
|
||||||
const checkCommissionInfo = () => {
|
const checkCommissionInfo = () => {
|
||||||
getCommissionSum({
|
getCommissionSum({
|
||||||
member_id
|
member_id
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
commissionStatistics.value = res.data;
|
commissionStatistics.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkCommissionInfo()
|
checkCommissionInfo()
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadMemberAccountLogList();
|
loadMemberAccountLogList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,7 +209,7 @@ const loadMemberAccountLogList = (page: number = 1) => {
|
|||||||
getCommissionList({
|
getCommissionList({
|
||||||
page: memberAccountLogTableData.page,
|
page: memberAccountLogTableData.page,
|
||||||
limit: memberAccountLogTableData.limit,
|
limit: memberAccountLogTableData.limit,
|
||||||
...memberAccountLogTableData.searchParam
|
...memberAccountLogTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
memberAccountLogTableData.loading = false
|
memberAccountLogTableData.loading = false
|
||||||
memberAccountLogTableData.data = res.data.data
|
memberAccountLogTableData.data = res.data.data
|
||||||
@ -221,7 +226,7 @@ const moneyDialog: Record<string, any> | null = ref(null)
|
|||||||
* 查看详情
|
* 查看详情
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const infoEvent = (data: any) => {
|
const infoEvent = (data: any) => {
|
||||||
moneyDialog.value.setFormData(data)
|
moneyDialog.value.setFormData(data)
|
||||||
moneyDialog.value.showDialog = true
|
moneyDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
@ -231,11 +236,10 @@ const router = useRouter()
|
|||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
*/
|
*/
|
||||||
const toMember = (member_id:number) => {
|
const toMember = (member_id: number) => {
|
||||||
router.push(`/member/detail?id=${member_id}`)
|
router.push(`/member/detail?id=${member_id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -28,9 +28,9 @@ import { t } from '@/lang'
|
|||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { addMemberLabel, updateMemberLabel, getMemberLabelInfo } from '@/app/api/member'
|
import { addMemberLabel, updateMemberLabel, getMemberLabelInfo } from '@/app/api/member'
|
||||||
|
|
||||||
let showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
let popTitle:string = '';
|
let popTitle:string = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
@ -39,7 +39,7 @@ const initialFormData = {
|
|||||||
label_id: '',
|
label_id: '',
|
||||||
label_name: '',
|
label_name: '',
|
||||||
memo: '',
|
memo: '',
|
||||||
sort: 0,
|
sort: 0
|
||||||
|
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
@ -49,19 +49,19 @@ const formRef = ref<FormInstance>()
|
|||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = computed(() => {
|
const formRules = computed(() => {
|
||||||
return {
|
return {
|
||||||
label_name: [
|
label_name: [
|
||||||
{ required: true, message: t('labelNamePlaceholder'), trigger: 'blur' }
|
{ required: true, message: t('labelNamePlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
sort:[
|
sort: [
|
||||||
{ validator: sortVerify, trigger: 'blur' }
|
{ validator: sortVerify, trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const sortVerify = (rule: any, value: any, callback: any) => {
|
const sortVerify = (rule: any, value: any, callback: any) => {
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
callback(new Error(t('sortVerifyOne')))
|
callback(new Error(t('sortVerifyOne')))
|
||||||
} else if (value.toString().indexOf(".") != -1) {
|
} else if (value.toString().indexOf('.') != -1) {
|
||||||
callback(new Error(t('sortVerifyTwo')))
|
callback(new Error(t('sortVerifyTwo')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
@ -76,19 +76,19 @@ 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.label_id ? updateMemberLabel : addMemberLabel
|
const save = formData.label_id ? updateMemberLabel : addMemberLabel
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
let data = formData
|
const data = formData
|
||||||
|
|
||||||
save(data).then(res => {
|
save(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
// showDialog.value = false
|
||||||
})
|
})
|
||||||
@ -100,15 +100,16 @@ const setFormData = async (row: any = null) => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
popTitle = t('addMemberLabel')
|
popTitle = t('addMemberLabel')
|
||||||
if(row){
|
if (row) {
|
||||||
popTitle = t('updateMemberLabel')
|
popTitle = t('updateMemberLabel')
|
||||||
const data = await (await getMemberLabelInfo(row.label_id)).data
|
const data = await (await getMemberLabelInfo(row.label_id)).data
|
||||||
if (data) Object.keys(formData).forEach((key: string) => {
|
if (data) {
|
||||||
if (data[key] != undefined) formData[key] = data[key]
|
Object.keys(formData).forEach((key: string) => {
|
||||||
})
|
if (data[key] != undefined) formData[key] = data[key]
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@ -13,12 +13,12 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('sex')" v-if="type == 'sex'">
|
<el-form-item :label="t('sex')" v-if="type == 'sex'">
|
||||||
<el-select v-model="saveData.sex" clearable :placeholder="t('sexPlaceholder')" class="input-width">
|
<el-select v-model="saveData.sex" clearable :placeholder="t('sexPlaceholder')" class="input-width">
|
||||||
<el-option :label="item['name']" :value="item['id']" v-for="item in sexSelectData" />
|
<el-option :label="item['name']" :value="item['id']" v-for="(item,index) in sexSelectData" :key="index" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('memberLabel')" v-if="type == 'member_label'">
|
<el-form-item :label="t('memberLabel')" v-if="type == 'member_label'">
|
||||||
<el-select v-model="saveData.member_label" multiple collapse-tags :placeholder="t('memberLabelPlaceholder')" class="input-width">
|
<el-select v-model="saveData.member_label" multiple collapse-tags :placeholder="t('memberLabelPlaceholder')" class="input-width">
|
||||||
<el-option :label="item['label_name']" :value="item['label_id']" v-for="item in labelSelectData" />
|
<el-option :label="item['label_name']" :value="item['label_id']" v-for="(item,index) in labelSelectData" :key="index"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -39,11 +39,11 @@ import type { FormInstance } from 'element-plus'
|
|||||||
import { editMemberDetail, getMemberLabelAll } from '@/app/api/member'
|
import { editMemberDetail, getMemberLabelAll } from '@/app/api/member'
|
||||||
|
|
||||||
// 修改类型
|
// 修改类型
|
||||||
let type = ref('')
|
const type = ref('')
|
||||||
let title = ref('')
|
const title = ref('')
|
||||||
// 会员id
|
// 会员id
|
||||||
let memberId = ref('')
|
const memberId = ref('')
|
||||||
let showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const sexSelectData = ref([
|
const sexSelectData = ref([
|
||||||
{
|
{
|
||||||
@ -58,14 +58,13 @@ const sexSelectData = ref([
|
|||||||
id: 2,
|
id: 2,
|
||||||
name: t('girlSex')
|
name: t('girlSex')
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
let labelSelectData = ref(null)
|
const labelSelectData = ref(null)
|
||||||
// 获取全部标签
|
// 获取全部标签
|
||||||
const getMemberLabelAllFn = async () => {
|
const getMemberLabelAllFn = async () => {
|
||||||
labelSelectData.value = await (await getMemberLabelAll()).data
|
labelSelectData.value = await (await getMemberLabelAll()).data
|
||||||
}
|
}
|
||||||
getMemberLabelAllFn();
|
getMemberLabelAllFn()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
@ -79,7 +78,6 @@ const initialFormData = {
|
|||||||
}
|
}
|
||||||
const saveData: Record<string, any> = reactive({ ...initialFormData })
|
const saveData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,7 +86,7 @@ const emit = defineEmits(['complete'])
|
|||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
let data = ref({
|
const data = ref({
|
||||||
member_id: memberId.value,
|
member_id: memberId.value,
|
||||||
field: type.value,
|
field: type.value,
|
||||||
value: saveData[type.value]
|
value: saveData[type.value]
|
||||||
@ -98,25 +96,24 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
// showDialog.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const setDialogType = async (row: any = null) => {
|
const setDialogType = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
type.value = row.type;
|
type.value = row.type
|
||||||
title.value = row.title;
|
title.value = row.title
|
||||||
memberId.value = row.id;
|
memberId.value = row.id
|
||||||
saveData[type.value] = row.data[type.value]
|
saveData[type.value] = row.data[type.value]
|
||||||
if (type.value == "member_label" && saveData[type.value]) {
|
if (type.value == 'member_label' && saveData[type.value]) {
|
||||||
saveData[type.value].forEach((item, index) => {
|
saveData[type.value].forEach((item:any, index:any) => {
|
||||||
saveData[type.value][index] = Number.parseFloat(item);
|
saveData[type.value][index] = Number.parseFloat(item)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@ -36,7 +36,6 @@
|
|||||||
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 { img } from '@/utils/common'
|
|
||||||
import { adjustBalance } from '@/app/api/member'
|
import { adjustBalance } from '@/app/api/member'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
@ -47,11 +46,11 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
member_id: 0,
|
member_id: 0,
|
||||||
balance:'',
|
balance: '',
|
||||||
memo:'',
|
memo: '',
|
||||||
adjust:'',
|
adjust: '',
|
||||||
account_data:'',
|
account_data: '',
|
||||||
adjust_type:1,
|
adjust_type: 1
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -64,9 +63,9 @@ const formRules = computed(() => {
|
|||||||
{ required: true, message: t('adjustBalancePlaceholder'), trigger: 'blur' },
|
{ required: true, message: t('adjustBalancePlaceholder'), trigger: 'blur' },
|
||||||
{
|
{
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
let adjust = Math.abs(parseFloat(formData.adjust));
|
const adjust = Math.abs(parseFloat(formData.adjust))
|
||||||
|
|
||||||
if(!adjust){
|
if (!adjust) {
|
||||||
callback(new Error(t('adjustBalancePlaceholder')))
|
callback(new Error(t('adjustBalancePlaceholder')))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ const formRules = computed(() => {
|
|||||||
},
|
},
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -86,20 +85,20 @@ const formRules = computed(() => {
|
|||||||
* 确认
|
* 确认
|
||||||
* @param formEl
|
* @param formEl
|
||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
formData.account_data = Math.abs(parseFloat(formData.adjust)) * formData.adjust_type;
|
formData.account_data = Math.abs(parseFloat(formData.adjust)) * formData.adjust_type
|
||||||
let data = formData
|
const data = formData
|
||||||
|
|
||||||
adjustBalance(data).then(res => {
|
adjustBalance(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
// showDialog.value = false
|
||||||
})
|
})
|
||||||
@ -107,7 +106,6 @@ const formRules = computed(() => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
|
|||||||
@ -61,20 +61,20 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
account_data: 0,
|
account_data: 0,
|
||||||
account_type:'',
|
account_type: '',
|
||||||
create_time:'',
|
create_time: '',
|
||||||
from_type:'',
|
from_type: '',
|
||||||
from_type_name:'',
|
from_type_name: '',
|
||||||
member_id:'',
|
member_id: '',
|
||||||
memo:'',
|
memo: '',
|
||||||
related_id:'',
|
related_id: '',
|
||||||
member: {
|
member: {
|
||||||
headimg:'',
|
headimg: '',
|
||||||
mobile:'',
|
mobile: '',
|
||||||
member_no: '',
|
member_no: '',
|
||||||
username:'',
|
username: '',
|
||||||
nickname:'',
|
nickname: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -87,10 +87,10 @@ const formRules = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
// const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|||||||
@ -1,39 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :title="t('moneyInfo')" width="550px" :destroy-on-close="true">
|
<el-dialog v-model="showDialog" :title="t('moneyInfo')" width="550px" :destroy-on-close="true">
|
||||||
<el-form :model="formData" label-width="110px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
<el-form :model="formData" label-width="110px" ref="formRef" :rules="formRules" class="page-form"
|
||||||
|
v-loading="loading">
|
||||||
|
|
||||||
<el-form-item :label="t('headimg')" >
|
<el-form-item :label="t('headimg')">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="formData.member.headimg" :src="img(formData.member.headimg)" alt="" >
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="formData.member.headimg"
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
:src="img(formData.member.headimg)" alt="">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memberId')" >
|
<el-form-item :label="t('memberId')">
|
||||||
<div class="input-width"> {{ formData.member.member_no }} </div>
|
<div class="input-width"> {{ formData.member.member_no }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('nickName')" >
|
<el-form-item :label="t('nickName')">
|
||||||
<div class="input-width"> {{ formData.member.nickname }} </div>
|
<div class="input-width"> {{ formData.member.nickname }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('mobile')" >
|
<el-form-item :label="t('mobile')">
|
||||||
<div class="input-width"> {{ formData.member.mobile }} </div>
|
<div class="input-width"> {{ formData.member.mobile }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('accountData')" >
|
<el-form-item :label="t('accountData')">
|
||||||
<div class="input-width"> {{ formData.account_data }} </div>
|
<div class="input-width"> {{ formData.account_data }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('fromType')" >
|
<el-form-item :label="t('fromType')">
|
||||||
<div class="input-width"> {{ formData.from_type_name }} </div>
|
<div class="input-width"> {{ formData.from_type_name }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memo')" >
|
<el-form-item :label="t('memo')">
|
||||||
<div class="input-width"> {{ formData.memo }} </div>
|
<div class="input-width"> {{ formData.memo }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('createTime')" >
|
<el-form-item :label="t('createTime')">
|
||||||
<div class="input-width"> {{ formData.create_time }} </div>
|
<div class="input-width"> {{ formData.create_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@ -61,20 +63,20 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
account_data: 0,
|
account_data: 0,
|
||||||
account_type:'',
|
account_type: '',
|
||||||
create_time:'',
|
create_time: '',
|
||||||
from_type:'',
|
from_type: '',
|
||||||
from_type_name:"",
|
from_type_name: '',
|
||||||
member_id:'',
|
member_id: '',
|
||||||
memo:'',
|
memo: '',
|
||||||
related_id:'',
|
related_id: '',
|
||||||
member: {
|
member: {
|
||||||
headimg:'',
|
headimg: '',
|
||||||
mobile:'',
|
mobile: '',
|
||||||
member_no: '',
|
member_no: '',
|
||||||
username:'',
|
username: '',
|
||||||
nickname:'',
|
nickname: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -87,10 +89,10 @@ const formRules = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
// const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|||||||
@ -57,17 +57,17 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
account_data: 0,
|
account_data: 0,
|
||||||
account_type:'',
|
account_type: '',
|
||||||
create_time:'',
|
create_time: '',
|
||||||
from_type:'',
|
from_type: '',
|
||||||
from_type_name:"",
|
from_type_name: '',
|
||||||
headimg:'',
|
headimg: '',
|
||||||
member_id:'',
|
member_id: '',
|
||||||
memo:'',
|
memo: '',
|
||||||
mobile:'',
|
mobile: '',
|
||||||
nickname:'',
|
nickname: '',
|
||||||
related_id:'',
|
related_id: '',
|
||||||
username:''
|
username: ''
|
||||||
|
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
@ -81,10 +81,10 @@ const formRules = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
// const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|||||||
@ -36,7 +36,6 @@
|
|||||||
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 { img } from '@/utils/common'
|
|
||||||
import { adjustPoint } from '@/app/api/member'
|
import { adjustPoint } from '@/app/api/member'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
@ -47,11 +46,11 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
member_id: 0,
|
member_id: 0,
|
||||||
point:'',
|
point: '',
|
||||||
memo:'',
|
memo: '',
|
||||||
adjust:'',
|
adjust: '',
|
||||||
account_data:'',
|
account_data: '',
|
||||||
adjust_type:1,
|
adjust_type: 1
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -64,11 +63,11 @@ const formRules = computed(() => {
|
|||||||
{ required: true, message: t('adjustPointPlaceholder'), trigger: 'blur' },
|
{ required: true, message: t('adjustPointPlaceholder'), trigger: 'blur' },
|
||||||
{
|
{
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
formData.adjust = Math.floor(formData.adjust);
|
formData.adjust = Math.floor(formData.adjust)
|
||||||
|
|
||||||
let adjust = Math.abs(parseFloat(formData.adjust));
|
const adjust = Math.abs(parseFloat(formData.adjust))
|
||||||
|
|
||||||
if(!adjust){
|
if (!adjust) {
|
||||||
callback(new Error(t('adjustPointPlaceholder')))
|
callback(new Error(t('adjustPointPlaceholder')))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ const formRules = computed(() => {
|
|||||||
},
|
},
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -88,20 +87,20 @@ const formRules = computed(() => {
|
|||||||
* 确认
|
* 确认
|
||||||
* @param formEl
|
* @param formEl
|
||||||
*/
|
*/
|
||||||
const confirm = async (formEl: FormInstance | undefined) => {
|
const confirm = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
|
|
||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
formData.account_data = Math.abs(parseFloat(formData.adjust)) * formData.adjust_type;
|
formData.account_data = Math.abs(parseFloat(formData.adjust)) * formData.adjust_type;
|
||||||
let data = formData
|
const data = formData
|
||||||
|
|
||||||
adjustPoint(data).then(res => {
|
adjustPoint(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(err => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
// showDialog.value = false
|
||||||
})
|
})
|
||||||
@ -112,7 +111,7 @@ const formRules = computed(() => {
|
|||||||
const emit = defineEmits(['complete'])
|
const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
if (row) {
|
if (row) {
|
||||||
Object.keys(formData).forEach((key: string) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
|
|||||||
@ -61,20 +61,20 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
account_data: 0,
|
account_data: 0,
|
||||||
account_type:'',
|
account_type: '',
|
||||||
create_time:'',
|
create_time: '',
|
||||||
from_type:'',
|
from_type: '',
|
||||||
from_type_name:"",
|
from_type_name: '',
|
||||||
member_id:'',
|
member_id: '',
|
||||||
memo:'',
|
memo: '',
|
||||||
related_id:'',
|
related_id: '',
|
||||||
member: {
|
member: {
|
||||||
headimg:'',
|
headimg: '',
|
||||||
mobile:'',
|
mobile: '',
|
||||||
member_no: '',
|
member_no: '',
|
||||||
username:'',
|
username: '',
|
||||||
nickname:'',
|
nickname: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -87,10 +87,10 @@ const formRules = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
// const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
if (row) {
|
if (row) {
|
||||||
Object.keys(formData).forEach((key: string) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
|
|||||||
@ -59,25 +59,25 @@ import EditMemberLabel from '@/app/views/member/components/edit-label.vue'
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let memberLabelTableData = reactive({
|
const memberLabelTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
"label_name":""
|
label_name: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadMemberLabelList();
|
loadMemberLabelList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,31 +3,37 @@
|
|||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
|
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
<el-button type="primary" @click="addEvent">{{ t('addMember') }}</el-button>
|
<el-button type="primary" @click="addEvent">{{ t('addMember') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="memberTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="memberTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('memberInfo')" prop="keyword">
|
<el-form-item :label="t('memberInfo')" prop="keyword">
|
||||||
<el-input v-model="memberTableData.searchParam.keyword" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
<el-input v-model="memberTableData.searchParam.keyword" class="w-[240px]"
|
||||||
|
:placeholder="t('memberInfoPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('registerChannel')" prop="register_channel">
|
<el-form-item :label="t('registerChannel')" prop="register_channel">
|
||||||
<el-select v-model="memberTableData.searchParam.register_channel" clearable :placeholder="t('channelPlaceholder')" class="input-width">
|
<el-select v-model="memberTableData.searchParam.register_channel" clearable
|
||||||
|
:placeholder="t('channelPlaceholder')" class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item" :value="key" v-for="(item, key) in channelList" />
|
<el-option :label="item" :value="key" v-for="(item, key) in channelList" :key="key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memberLabel')" prop="member_label">
|
<el-form-item :label="t('memberLabel')" prop="member_label">
|
||||||
<el-select v-model="memberTableData.searchParam.member_label" collapse-tags clearable :placeholder="t('memberLabelPlaceholder')" class="input-width">
|
<el-select v-model="memberTableData.searchParam.member_label" collapse-tags clearable
|
||||||
<el-option :label="t('selectPlaceholder')" value=""/>
|
:placeholder="t('memberLabelPlaceholder')" class="input-width">
|
||||||
<el-option :label="item['label_name']" :value="item['label_id']" v-for="item in labelSelectData" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
|
<el-option :label="item['label_name']" :value="item['label_id']"
|
||||||
|
v-for="(item, index) in labelSelectData" :key="index" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" prop="create_time">
|
<el-form-item :label="t('createTime')" prop="create_time">
|
||||||
<el-date-picker v-model="memberTableData.searchParam.create_time" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
|
<el-date-picker v-model="memberTableData.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-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadMemberList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadMemberList()">{{ t('search') }}</el-button>
|
||||||
@ -46,7 +52,8 @@
|
|||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<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-if="row.headimg" :src="img(row.headimg)" alt="">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else
|
||||||
|
src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
<div class="flex flex flex-col">
|
<div class="flex flex flex-col">
|
||||||
<span>{{ row.nickname || '' }}</span>
|
<span>{{ row.nickname || '' }}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -63,21 +70,24 @@
|
|||||||
<el-table-column prop="member_label" :label="t('lable')" min-width="120" align="center">
|
<el-table-column prop="member_label" :label="t('lable')" min-width="120" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex flex-col items-start">
|
<div class="flex flex-col items-start">
|
||||||
<div v-for="(item, key) in row.member_label_array" class="my-[3px]">
|
<div v-for="(item, key) in row.member_label_array" class="my-[3px]" :key="key">
|
||||||
<el-tag class="ml-[13px]" type="info">{{item.label_name}}</el-tag>
|
<el-tag class="ml-[13px]" type="info">{{ item.label_name }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="register_channel_name" :label="t('registerChannel')" min-width="110" align="center"/>
|
<el-table-column prop="register_channel_name" :label="t('registerChannel')" min-width="110"
|
||||||
|
align="center" />
|
||||||
|
|
||||||
<el-table-column prop="member_label" :label="t('status')" min-width="120" align="center">
|
<el-table-column prop="member_label" :label="t('status')" min-width="120" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag type="success" v-if="row.status == 1" @click="lockMember(row, 0)" class="cursor-pointer">{{t('normal')}}</el-tag>
|
<el-tag type="success" v-if="row.status == 1" @click="lockMember(row, 0)"
|
||||||
<el-tag type="error" v-else @click="lockMember(row, 1)" class="cursor-pointer">{{t('lock')}}</el-tag>
|
class="cursor-pointer">{{ t('normal') }}</el-tag>
|
||||||
</template>
|
<el-tag type="error" v-else @click="lockMember(row, 1)"
|
||||||
</el-table-column>
|
class="cursor-pointer">{{ t('lock') }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column :label="t('createTime')" min-width="150" align="center">
|
<el-table-column :label="t('createTime')" min-width="150" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.create_time || '' }}
|
{{ row.create_time || '' }}
|
||||||
@ -117,15 +127,14 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { addMember, getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus,deleteMember } from '@/app/api/member'
|
import { addMember, getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus, deleteMember } from '@/app/api/member'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import AddMember from '@/app/views/member/components/add-member.vue'
|
import AddMember from '@/app/views/member/components/add-member.vue'
|
||||||
import EditMember from '@/app/views/member/components/edit-member.vue'
|
import EditMember from '@/app/views/member/components/edit-member.vue'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
const memberTableData = reactive({
|
const memberTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
@ -136,7 +145,7 @@ const memberTableData = reactive({
|
|||||||
keyword: '',
|
keyword: '',
|
||||||
register_type: '',
|
register_type: '',
|
||||||
member_label: '',
|
member_label: '',
|
||||||
register_channel:'',
|
register_channel: '',
|
||||||
create_time: []
|
create_time: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -148,21 +157,19 @@ const channelList = ref([])
|
|||||||
const setChannelList = async () => {
|
const setChannelList = async () => {
|
||||||
channelList.value = await (await getRegisterChannelType({})).data
|
channelList.value = await (await getRegisterChannelType({})).data
|
||||||
}
|
}
|
||||||
setChannelList();
|
setChannelList()
|
||||||
|
|
||||||
|
|
||||||
// 获取全部标签
|
// 获取全部标签
|
||||||
let labelSelectData = ref([])
|
const labelSelectData = ref([])
|
||||||
const getMemberLabelAllFn = async () => {
|
const getMemberLabelAllFn = async () => {
|
||||||
labelSelectData.value = await (await getMemberLabelAll()).data
|
labelSelectData.value = await (await getMemberLabelAll()).data
|
||||||
}
|
}
|
||||||
getMemberLabelAllFn();
|
getMemberLabelAllFn()
|
||||||
|
|
||||||
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadMemberList();
|
loadMemberList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取会员列表
|
// 获取会员列表
|
||||||
@ -188,30 +195,29 @@ const router = useRouter()
|
|||||||
const addMemberDialog: Record<string, any> | null = ref(null)
|
const addMemberDialog: Record<string, any> | null = ref(null)
|
||||||
const editMemberDialog: Record<string, any> | null = ref(null)
|
const editMemberDialog: Record<string, any> | null = ref(null)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取标签
|
* 获取标签
|
||||||
*/
|
*/
|
||||||
function memberLable(res: any) {
|
function memberLable(res: any) {
|
||||||
let data;
|
let data
|
||||||
if (!res.member_label_array) return '';
|
if (!res.member_label_array) return ''
|
||||||
data = res.member_label_array.map((item) => {
|
data = res.member_label_array.map((item:any) => {
|
||||||
return item.label_name;
|
return item.label_name
|
||||||
});
|
})
|
||||||
data = data.toString();
|
data = data.toString()
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置标签
|
* 设置标签
|
||||||
*/
|
*/
|
||||||
function setMemberLable(res: any) {
|
function setMemberLable (res: any) {
|
||||||
let data = ref({
|
const data = ref({
|
||||||
type: 'member_label',
|
type: 'member_label',
|
||||||
id: res.member_id,
|
id: res.member_id,
|
||||||
title: t('setLable'),
|
title: t('setLable'),
|
||||||
data: res
|
data: res
|
||||||
});
|
})
|
||||||
editMemberDialog.value.setDialogType(data.value)
|
editMemberDialog.value.setDialogType(data.value)
|
||||||
editMemberDialog.value.showDialog = true
|
editMemberDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
@ -220,7 +226,6 @@ function setMemberLable(res: any) {
|
|||||||
* 删除
|
* 删除
|
||||||
*/
|
*/
|
||||||
function deleteEvent(res: any) {
|
function deleteEvent(res: any) {
|
||||||
|
|
||||||
ElMessageBox.confirm(t('memberDeleteTips'), t('warning'),
|
ElMessageBox.confirm(t('memberDeleteTips'), t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@ -229,14 +234,12 @@ function deleteEvent(res: any) {
|
|||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
deleteMember(res.member_id).then(() => {
|
deleteMember(res.member_id).then(() => {
|
||||||
loadMemberList();
|
loadMemberList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加会员
|
* 添加会员
|
||||||
*/
|
*/
|
||||||
@ -261,7 +264,7 @@ const detailEvent = (data: any) => {
|
|||||||
/**
|
/**
|
||||||
* 变更会员状态
|
* 变更会员状态
|
||||||
*/
|
*/
|
||||||
const lockMember = (res, status) => {
|
const lockMember = (res:any, status:any) => {
|
||||||
editMemberStatus({
|
editMemberStatus({
|
||||||
status: status,
|
status: status,
|
||||||
member_ids: [res.member_id]
|
member_ids: [res.member_id]
|
||||||
|
|||||||
@ -237,16 +237,16 @@
|
|||||||
</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 { getMemberInfo } from '@/app/api/member'
|
import { getMemberInfo } from '@/app/api/member'
|
||||||
import { ElMessageBox, FormInstance, ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import PointEdit from '@/app/views/member/components/member-point-edit.vue'
|
import PointEdit from '@/app/views/member/components/member-point-edit.vue'
|
||||||
import BalanceEdit from '@/app/views/member/components/member-balance-edit.vue'
|
import BalanceEdit from '@/app/views/member/components/member-balance-edit.vue'
|
||||||
import EditMember from '@/app/views/member/components/edit-member.vue'
|
import EditMember from '@/app/views/member/components/edit-member.vue'
|
||||||
import colorGradient from '../../../../uniapp/src/uni_modules/vk-uview-ui/libs/function/colorGradient'
|
// import colorGradient from '../../../../uniapp/src/uni_modules/vk-uview-ui/libs/function/colorGradient'
|
||||||
import useAppStore from '@/stores/modules/app'
|
import useAppStore from '@/stores/modules/app'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@ -260,34 +260,34 @@ const id: number = parseInt(route.query.id || 0)
|
|||||||
const formData: any = reactive({ member_label_name: '' })
|
const formData: any = reactive({ member_label_name: '' })
|
||||||
|
|
||||||
const getMemberInfoFn = async () => {
|
const getMemberInfoFn = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if (id) {
|
if (id) {
|
||||||
const data = await (await getMemberInfo(id)).data
|
const data = await (await getMemberInfo(id)).data
|
||||||
if (!data || Object.keys(data).length == 0) {
|
if (!data || Object.keys(data).length == 0) {
|
||||||
ElMessage.error(t('memberNull'))
|
ElMessage.error(t('memberNull'))
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.go(-1)
|
router.go(-1)
|
||||||
}, 2000)
|
}, 2000)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(data).forEach((item) => {
|
Object.keys(data).forEach((item) => {
|
||||||
formData[item] = data[item]
|
formData[item] = data[item]
|
||||||
})
|
})
|
||||||
|
|
||||||
if (formData?.member_label_array && Object.keys(formData.member_label_array)?.length) {
|
if (formData?.member_label_array && Object.keys(formData.member_label_array)?.length) {
|
||||||
formData.member_label = Object.values(formData.member_label_array).map((item: any, index) => {
|
formData.member_label = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||||
return item.label_id
|
return item.label_id
|
||||||
})
|
})
|
||||||
|
|
||||||
formData.member_label_name = Object.values(formData.member_label_array).map((item: any, index) => {
|
formData.member_label_name = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||||
return item.label_name
|
return item.label_name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
} else {
|
} else {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getMemberInfoFn()
|
getMemberInfoFn()
|
||||||
|
|
||||||
@ -299,29 +299,29 @@ const editMemberDialog: Record<string, any> | null = ref(null)
|
|||||||
* 修改会员信息
|
* 修改会员信息
|
||||||
*/
|
*/
|
||||||
const editMemberInfo = (type: any) => {
|
const editMemberInfo = (type: any) => {
|
||||||
const data = ref({
|
const data = ref({
|
||||||
type,
|
type,
|
||||||
id,
|
id,
|
||||||
data: formData
|
data: formData
|
||||||
})
|
})
|
||||||
editMemberDialog.value.setDialogType(data.value)
|
editMemberDialog.value.setDialogType(data.value)
|
||||||
editMemberDialog.value.showDialog = true
|
editMemberDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调整积分
|
* 调整积分
|
||||||
*/
|
*/
|
||||||
const adjustPoint = (data: any) => {
|
const adjustPoint = (data: any) => {
|
||||||
pointDialog.value.setFormData(data)
|
pointDialog.value.setFormData(data)
|
||||||
pointDialog.value.showDialog = true
|
pointDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调整余额
|
* 调整余额
|
||||||
*/
|
*/
|
||||||
const adjustBalance = (data: any) => {
|
const adjustBalance = (data: any) => {
|
||||||
balanceDialog.value.setFormData(data)
|
balanceDialog.value.setFormData(data)
|
||||||
balanceDialog.value.showDialog = true
|
balanceDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -330,21 +330,21 @@ const router = useRouter()
|
|||||||
* 积分详情
|
* 积分详情
|
||||||
*/
|
*/
|
||||||
const infoPoint = () => {
|
const infoPoint = () => {
|
||||||
router.push(`/member/point?id=${id}`)
|
router.push(`/member/point?id=${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 余额详情
|
* 余额详情
|
||||||
*/
|
*/
|
||||||
const infoBalance = () => {
|
const infoBalance = () => {
|
||||||
router.push(`/member/balance?id=${id}`)
|
router.push(`/member/balance?id=${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 佣金详情
|
* 佣金详情
|
||||||
*/
|
*/
|
||||||
const infoCommission = () => {
|
const infoCommission = () => {
|
||||||
router.push(`/member/commission?id=${id}`)
|
router.push(`/member/commission?id=${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,52 +2,52 @@
|
|||||||
<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 justify-between items-center mb-[5px]">
|
<div class="flex justify-between items-center mb-[5px]">
|
||||||
<span class="text-[20x]">{{pageName}}</span>
|
<span class="text-[20x]">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
<el-card class="box-card !border-none base-bg !px-[35px]" shadow="never">
|
||||||
<el-row class="flex">
|
<el-row class="flex">
|
||||||
<el-col :span="12" class="min-w-[100px]">
|
<el-col :span="12" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="pointStatistics.point_get ? Number.parseInt(pointStatistics.point_get) : '0'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="pointStatistics.point_get ? Number.parseInt(pointStatistics.point_get) : '0'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('pointGet') }}</span>
|
<span>{{ t('pointGet') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" class="min-w-[100px]">
|
<el-col :span="12" class="min-w-[100px]">
|
||||||
<div class="statistic-card">
|
<div class="statistic-card">
|
||||||
<el-statistic :value="pointStatistics.point_use ? Number.parseInt(pointStatistics.point_use) : '0'"></el-statistic>
|
<el-statistic
|
||||||
|
:value="pointStatistics.point_use ? Number.parseInt(pointStatistics.point_use) : '0'"></el-statistic>
|
||||||
<div class="statistic-footer">
|
<div class="statistic-footer">
|
||||||
<div class="footer-item text-[14px] text-[#666]">
|
<div class="footer-item text-[14px] text-[#666]">
|
||||||
<span>{{ t('pointUse') }}</span>
|
<span>{{ t('pointUse') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||||
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]"
|
||||||
|
:placeholder="t('memberInfoPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('fromType')" prop="from_type">
|
<el-form-item :label="t('fromType')" prop="from_type">
|
||||||
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">
|
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable
|
||||||
|
:placeholder="t('fromTypePlaceholder')" class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item.name" :value="key" v-for="(item,key) in fromTypeList" />
|
<el-option :label="item.name" :value="key" v-for="(item, key) in fromTypeList" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('createTime')" prop="create_time">
|
<el-form-item :label="t('createTime')" prop="create_time">
|
||||||
<el-date-picker
|
<el-date-picker v-model="memberAccountLogTableData.searchParam.create_time" type="datetimerange"
|
||||||
v-model="memberAccountLogTableData.searchParam.create_time"
|
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||||
type="datetimerange"
|
:end-placeholder="t('endDate')" />
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
:start-placeholder="t('startDate')"
|
|
||||||
:end-placeholder="t('endDate')"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadMemberAccountLogList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadMemberAccountLogList()">{{ t('search') }}</el-button>
|
||||||
@ -68,46 +68,50 @@
|
|||||||
{{ row.member.member_no }}
|
{{ row.member.member_no }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('memberInfo')" min-width="150" :show-overflow-tooltip="true">
|
<el-table-column :label="t('memberInfo')" min-width="150" :show-overflow-tooltip="true">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="" >
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg"
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
:src="img(row.member.headimg)" alt="">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else
|
||||||
|
src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
<div class="flex flex flex-col">
|
<div class="flex flex flex-col">
|
||||||
<span class="">{{ row.member.nickname || '' }}</span>
|
<span class="">{{ row.member.nickname || '' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="mobile" :label="t('mobile')" min-width="100">
|
<el-table-column prop="mobile" :label="t('mobile')" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.member.mobile || '' }}
|
{{ row.member.mobile || '' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="account_data" :label="t('accountData')" min-width="80" align="right">
|
<el-table-column prop="account_data" :label="t('accountData')" min-width="80" align="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="row.account_data >= 0">+{{ row.account_data }}</span>
|
<span v-if="row.account_data >= 0">+{{ row.account_data }}</span>
|
||||||
<span v-else>{{ row.account_data }}</span>
|
<span v-else>{{ row.account_data }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="account_sum" :label="t('accountSum')" min-width="120" align="right"/>
|
<el-table-column prop="account_sum" :label="t('accountSum')" min-width="120" align="right" />
|
||||||
|
|
||||||
<el-table-column prop="from_type_name" :label="t('fromType')" min-width="180" align="center"/>
|
<el-table-column prop="from_type_name" :label="t('fromType')" min-width="180" align="center" />
|
||||||
<el-table-column prop="create_time" :show-overflow-tooltip="true" :label="t('createTime')" min-width="150" />
|
<el-table-column prop="create_time" :show-overflow-tooltip="true" :label="t('createTime')"
|
||||||
|
min-width="150" />
|
||||||
|
|
||||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
||||||
<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>
|
||||||
</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="memberAccountLogTableData.page" v-model:page-size="memberAccountLogTableData.limit"
|
<el-pagination v-model:current-page="memberAccountLogTableData.page"
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="memberAccountLogTableData.total"
|
v-model:page-size="memberAccountLogTableData.limit" layout="total, sizes, prev, pager, next, jumper"
|
||||||
@size-change="loadMemberAccountLogList()" @current-change="loadMemberAccountLogList" />
|
:total="memberAccountLogTableData.total" @size-change="loadMemberAccountLogList()"
|
||||||
|
@current-change="loadMemberAccountLogList" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -118,61 +122,60 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getChangeTypeList,getPointList,getPointSum } from '@/app/api/member'
|
import { getChangeTypeList, getPointList, getPointSum } from '@/app/api/member'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { FormInstance } from 'element-plus'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import pointInfo from '@/app/views/member/components/member-point-info.vue'
|
import pointInfo from '@/app/views/member/components/member-point-info.vue'
|
||||||
import { useRouter,useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const member_id: number = parseInt(route.query.id || 0)
|
const member_id: number = parseInt(route.query.id || 0)
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let memberAccountLogTableData = reactive({
|
const memberAccountLogTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam:{
|
searchParam: {
|
||||||
keywords:"",
|
keywords: '',
|
||||||
from_type:"",
|
from_type: '',
|
||||||
create_time:"",
|
create_time: '',
|
||||||
mobile:"",
|
mobile: '',
|
||||||
member_id:member_id
|
member_id: member_id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取积分总计
|
* 获取积分总计
|
||||||
*/
|
*/
|
||||||
const pointStatistics = ref([])
|
const pointStatistics = ref([])
|
||||||
const checkPointInfo = () => {
|
const checkPointInfo = () => {
|
||||||
getPointSum({
|
getPointSum({
|
||||||
member_id
|
member_id
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
pointStatistics.value = res.data;
|
pointStatistics.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkPointInfo()
|
checkPointInfo()
|
||||||
|
|
||||||
let fromTypeList = ref([])
|
const fromTypeList = ref([])
|
||||||
|
|
||||||
const setFromTypeList = async () => {
|
const setFromTypeList = async () => {
|
||||||
fromTypeList.value = await (await getChangeTypeList('point')).data
|
fromTypeList.value = await (await getChangeTypeList('point')).data
|
||||||
}
|
}
|
||||||
|
|
||||||
setFromTypeList();
|
setFromTypeList()
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined)=>{
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields();
|
formEl.resetFields()
|
||||||
loadMemberAccountLogList();
|
loadMemberAccountLogList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 获取会员账单表列表
|
* 获取会员账单表列表
|
||||||
@ -184,7 +187,7 @@ const loadMemberAccountLogList = (page: number = 1) => {
|
|||||||
getPointList({
|
getPointList({
|
||||||
page: memberAccountLogTableData.page,
|
page: memberAccountLogTableData.page,
|
||||||
limit: memberAccountLogTableData.limit,
|
limit: memberAccountLogTableData.limit,
|
||||||
...memberAccountLogTableData.searchParam
|
...memberAccountLogTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
memberAccountLogTableData.loading = false
|
memberAccountLogTableData.loading = false
|
||||||
memberAccountLogTableData.data = res.data.data
|
memberAccountLogTableData.data = res.data.data
|
||||||
@ -201,7 +204,7 @@ const pointDialog: Record<string, any> | null = ref(null)
|
|||||||
* 查看详情
|
* 查看详情
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
const infoEvent = (data: any) => {
|
const infoEvent = (data: any) => {
|
||||||
pointDialog.value.setFormData(data)
|
pointDialog.value.setFormData(data)
|
||||||
pointDialog.value.showDialog = true
|
pointDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
@ -211,11 +214,10 @@ const router = useRouter()
|
|||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
*/
|
*/
|
||||||
const toMember = (member_id:number) => {
|
const toMember = (member_id: number) => {
|
||||||
router.push(`/member/detail?id=${member_id}`)
|
router.push(`/member/detail?id=${member_id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -70,7 +70,7 @@ import type { FormInstance } from 'element-plus'
|
|||||||
import { getRechargeOrderInfo } from '@/app/api/order'
|
import { getRechargeOrderInfo } from '@/app/api/order'
|
||||||
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'
|
||||||
|
|
||||||
const tabbarStore = useTabbarStore()
|
const tabbarStore = useTabbarStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|||||||
@ -2,28 +2,30 @@
|
|||||||
<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 justify-between items-center mb-[5px]">
|
<div class="flex justify-between items-center mb-[5px]">
|
||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-card class="box-card !border-none table-search-wra base-bg !px-[35px]" shadow="never">
|
<el-card class="box-card !border-none table-search-wra base-bg !px-[35px]" shadow="never">
|
||||||
<el-row class="flex">
|
<el-row class="flex">
|
||||||
<el-col :span="12" class="min-w-[100px]">
|
<el-col :span="12" class="min-w-[100px]">
|
||||||
<el-statistic :value="rechargeStatistics.recharge_money ? Number.parseFloat(rechargeStatistics.recharge_money).toFixed(2) : '0.00'">
|
<el-statistic
|
||||||
<template #title>
|
:value="rechargeStatistics.recharge_money ? Number.parseFloat(rechargeStatistics.recharge_money).toFixed(2) : '0.00'">
|
||||||
<div class="text-[14px] mb-[9px]">{{ t('totalRechargeMoney') }}</div>
|
<template #title>
|
||||||
</template>
|
<div class="text-[14px] mb-[9px]">{{ t('totalRechargeMoney') }}</div>
|
||||||
</el-statistic>
|
</template>
|
||||||
</el-col>
|
</el-statistic>
|
||||||
<el-col :span="12" class="min-w-[100px]">
|
</el-col>
|
||||||
<el-statistic :value="rechargeStatistics.recharge_refund_money ? Number.parseFloat(rechargeStatistics.recharge_refund_money).toFixed(2) : '0.00'">
|
<el-col :span="12" class="min-w-[100px]">
|
||||||
<template #title>
|
<el-statistic
|
||||||
<div class="text-[14px] mb-[9px]">{{ t('totalRechargeRefundMoney') }}</div>
|
:value="rechargeStatistics.recharge_refund_money ? Number.parseFloat(rechargeStatistics.recharge_refund_money).toFixed(2) : '0.00'">
|
||||||
</template>
|
<template #title>
|
||||||
</el-statistic>
|
<div class="text-[14px] mb-[9px]">{{ t('totalRechargeRefundMoney') }}</div>
|
||||||
</el-col>
|
</template>
|
||||||
|
</el-statistic>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||||
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="orderTableData.searchParam" ref="searchFormRef">
|
||||||
@ -34,35 +36,41 @@
|
|||||||
<el-form-item :label="t('orderFromName')" prop="order_from">
|
<el-form-item :label="t('orderFromName')" prop="order_from">
|
||||||
<el-select v-model="orderTableData.searchParam.order_from" clearable class="input-width">
|
<el-select v-model="orderTableData.searchParam.order_from" clearable class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item" :value="key" v-for="(item, key) in channelList" />
|
<el-option :label="item" :value="key" v-for="(item, key) in channelList" :key="key"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('orderStatus')" prop="order_status">
|
<el-form-item :label="t('orderStatus')" prop="order_status">
|
||||||
<el-select v-model="orderTableData.searchParam.order_status" clearable class="input-width">
|
<el-select v-model="orderTableData.searchParam.order_status" clearable class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item['name']" :value="item['status']" v-for="item in statusList" />
|
<el-option :label="item['name']" :value="item['status']" v-for="(item,index) in statusList" :key="index"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('createTime')" prop="create_time">
|
<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-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-form-item :label="t('rechargeMoney')">
|
<el-form-item :label="t('rechargeMoney')">
|
||||||
<div class="region-input">
|
<div class="region-input">
|
||||||
<el-form-item prop="start_money">
|
<el-form-item prop="start_money">
|
||||||
<input type="text" :placeholder="t('startMoney')" v-model="orderTableData.searchParam.start_money">
|
<input type="text" :placeholder="t('startMoney')"
|
||||||
|
v-model="orderTableData.searchParam.start_money">
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<span class="separator">-</span>
|
<span class="separator">-</span>
|
||||||
<el-form-item prop="end_money">
|
<el-form-item prop="end_money">
|
||||||
<input type="text" :placeholder="t('endMoney')" v-model="orderTableData.searchParam.end_money">
|
<input type="text" :placeholder="t('endMoney')"
|
||||||
|
v-model="orderTableData.searchParam.end_money">
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('payTime')">
|
<el-form-item :label="t('payTime')">
|
||||||
<el-date-picker v-model="orderTableData.searchParam.pay_time" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
|
<el-date-picker v-model="orderTableData.searchParam.pay_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-form-item>
|
<el-form-item>
|
||||||
@ -81,8 +89,10 @@
|
|||||||
<el-table-column :show-overflow-tooltip="true" :label="t('member')" align="left" min-width="140">
|
<el-table-column :show-overflow-tooltip="true" :label="t('member')" align="left" min-width="140">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="flex items-center cursor-pointer " @click="toMember(row.member.member_id)">
|
<div class="flex items-center cursor-pointer " @click="toMember(row.member.member_id)">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg"
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
:src="img(row.member.headimg)" alt="">
|
||||||
|
<img class="w-[50px] h-[50px] mr-[10px]" v-else
|
||||||
|
src="@/app/assets/images/default_headimg.png" alt="">
|
||||||
<div class="flex flex flex-col">
|
<div class="flex flex flex-col">
|
||||||
<span class="">{{ row.member.nickname || '' }}</span>
|
<span class="">{{ row.member.nickname || '' }}</span>
|
||||||
<span class="">{{ row.member.mobile || '' }}</span>
|
<span class="">{{ row.member.mobile || '' }}</span>
|
||||||
@ -91,7 +101,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="order_no" :show-overflow-tooltip="true" :label="t('rechargeNo')" align="center" min-width="140" />
|
<el-table-column prop="order_no" :show-overflow-tooltip="true" :label="t('rechargeNo')" align="center"
|
||||||
|
min-width="140" />
|
||||||
|
|
||||||
<el-table-column prop="order_money" :label="t('rechargeMoney')" align="center" min-width="140" />
|
<el-table-column prop="order_money" :label="t('rechargeMoney')" align="center" min-width="140" />
|
||||||
|
|
||||||
@ -120,10 +131,13 @@
|
|||||||
<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) && row.is_enable_refund && row.refund_status == 0" type="primary" link @click="refundFn(row)">{{ t('refundBtn') }}</el-button>
|
<el-button
|
||||||
|
v-if="[1, 10].includes(row.order_status_info.status) && row.is_enable_refund && row.refund_status == 0"
|
||||||
|
type="primary" link @click="refundFn(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" :key="index">
|
||||||
<el-button type="primary" link @click="orderEvent(row, item.class)">{{ item.name }}</el-button>
|
<el-button type="primary" link @click="orderEvent(row, item.class)">{{ item.name
|
||||||
|
}}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -158,7 +172,7 @@ import { getChannelType } from '@/app/api/sys'
|
|||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { AnyObject } from '@/types/global'
|
import { AnyObject } from '@/types/global'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import { img } from '@/utils/common'
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
@ -203,7 +217,7 @@ const statusList = ref([])
|
|||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const setCategoryList = async () => {
|
const setCategoryList = async () => {
|
||||||
statusList.value = await (await getRechargeOrderStatusList({})).data
|
statusList.value = await (await getRechargeOrderStatusList()).data
|
||||||
}
|
}
|
||||||
setCategoryList()
|
setCategoryList()
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
<el-form-item :label="t('refundStatus')" prop="status">
|
<el-form-item :label="t('refundStatus')" prop="status">
|
||||||
<el-select v-model="refundTableData.searchParam.status" clearable class="input-width">
|
<el-select v-model="refundTableData.searchParam.status" clearable class="input-width">
|
||||||
<el-option :label="t('selectPlaceholder')" value="" />
|
<el-option :label="t('selectPlaceholder')" value="" />
|
||||||
<el-option :label="item.name" :value="key" v-for="(item, key) in refundList" />
|
<el-option :label="item.name" :value="key" v-for="(item, key) in refundList" :key="key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('refundTime')" prop="create_time">
|
<el-form-item :label="t('refundTime')" prop="create_time">
|
||||||
@ -152,85 +152,85 @@ const route = useRoute()
|
|||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
const refundTableData = reactive({
|
const refundTableData = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: [],
|
||||||
searchParam: {
|
searchParam: {
|
||||||
refund_no: '',
|
refund_no: '',
|
||||||
// member_id,
|
// member_id,
|
||||||
create_time: [],
|
create_time: [],
|
||||||
status: '',
|
status: '',
|
||||||
keywords: '',
|
keywords: '',
|
||||||
order_no: ''
|
order_no: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|
||||||
formEl.resetFields()
|
formEl.resetFields()
|
||||||
loadRefundList()
|
loadRefundList()
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 获取退款列表
|
* 获取退款列表
|
||||||
*/
|
*/
|
||||||
const loadRefundList = (page: number = 1) => {
|
const loadRefundList = (page: number = 1) => {
|
||||||
refundTableData.loading = true
|
refundTableData.loading = true
|
||||||
refundTableData.page = page
|
refundTableData.page = page
|
||||||
|
|
||||||
getRechargeRefund({
|
getRechargeRefund({
|
||||||
page: refundTableData.page,
|
page: refundTableData.page,
|
||||||
limit: refundTableData.limit,
|
limit: refundTableData.limit,
|
||||||
...refundTableData.searchParam
|
...refundTableData.searchParam
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
refundTableData.loading = false
|
refundTableData.loading = false
|
||||||
refundTableData.data = res.data.data
|
refundTableData.data = res.data.data
|
||||||
refundTableData.total = res.data.total
|
refundTableData.total = res.data.total
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
refundTableData.loading = false
|
refundTableData.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
loadRefundList()
|
loadRefundList()
|
||||||
|
|
||||||
const refundList = ref([])
|
const refundList = ref([])
|
||||||
const checkRefundList = () => {
|
const checkRefundList = () => {
|
||||||
getRechargeRefundStatus().then(res => {
|
getRechargeRefundStatus().then(res => {
|
||||||
refundList.value = res.data
|
refundList.value = res.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkRefundList()
|
checkRefundList()
|
||||||
|
|
||||||
const refundStat = reactive({
|
const refundStat = reactive({
|
||||||
refund_all_money: 0.00,
|
refund_all_money: 0.00,
|
||||||
refund_have_money: 0.00,
|
refund_have_money: 0.00,
|
||||||
refund_Success_money: 0.00,
|
refund_Success_money: 0.00,
|
||||||
refund_fail_moey: 0.00
|
refund_fail_moey: 0.00
|
||||||
})
|
})
|
||||||
const checkRefundStat = () => {
|
const checkRefundStat = () => {
|
||||||
getRechargeRefundStat().then(res => {
|
getRechargeRefundStat().then(res => {
|
||||||
refundStat.refund_all_money = res.data.all.money
|
refundStat.refund_all_money = res.data.all.money
|
||||||
refundStat.refund_have_money = res.data.have.money
|
refundStat.refund_have_money = res.data.have.money
|
||||||
refundStat.refund_Success_money = res.data['3'].money
|
refundStat.refund_Success_money = res.data['3'].money
|
||||||
refundStat.refund_fail_moey = res.data['-1'].money
|
refundStat.refund_fail_moey = res.data['-1'].money
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
checkRefundStat()
|
checkRefundStat()
|
||||||
|
|
||||||
const refundInfoShowDialog = ref(false)
|
const refundInfoShowDialog = ref(false)
|
||||||
const refundInfo = ref({})
|
const refundInfo = ref({})
|
||||||
|
|
||||||
const infoEvent = (info) => {
|
const infoEvent = (info:any) => {
|
||||||
refundInfo.value = info
|
refundInfo.value = info
|
||||||
refundInfoShowDialog.value = true
|
refundInfoShowDialog.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
*/
|
*/
|
||||||
const toMember = (memberId: number) => {
|
const toMember = (memberId: number) => {
|
||||||
router.push(`/member/detail?id=${memberId}`)
|
router.push(`/member/detail?id=${memberId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<span class="text-[20px]">{{pageName}}</span>
|
<span class="text-[20px]">{{pageName}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form :model="formData" label-width="150px" ref="ruleFormRef" :rules="formRules" class="page-form" v-loading="loading">
|
<el-form :model="formData" label-width="150px" ref="ruleFormRef" class="page-form" v-loading="loading">
|
||||||
<el-card class="box-card !border-none" shadow="never">
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
|
|
||||||
<h3 class="panel-title !text-sm">{{ t('admin') }}</h3>
|
<h3 class="panel-title !text-sm">{{ t('admin') }}</h3>
|
||||||
@ -45,29 +45,29 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getConfigLogin, setConfigLogin } from '@/app/api/sys'
|
import { getConfigLogin, setConfigLogin } from '@/app/api/sys'
|
||||||
import { FormRules, FormInstance } from 'element-plus'
|
import { FormInstance } from 'element-plus'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
|
|
||||||
const loading = ref(true),
|
const loading = ref(true)
|
||||||
ruleFormRef = ref<FormInstance>(),
|
const ruleFormRef = ref<FormInstance>()
|
||||||
formData = reactive<Record<string, number | string>>({
|
const formData = reactive<Record<string, number | string>>({
|
||||||
is_captcha: 0,
|
is_captcha: 0,
|
||||||
is_site_captcha: 0,
|
is_site_captcha: 0,
|
||||||
bg: '',
|
bg: '',
|
||||||
site_bg: ''
|
site_bg: ''
|
||||||
});
|
})
|
||||||
|
|
||||||
const getFormData = async (id: number = 0) => {
|
const getFormData = async (id: number = 0) => {
|
||||||
const data = await (await getConfigLogin()).data
|
const data = await (await getConfigLogin()).data
|
||||||
Object.keys(formData).forEach((key: string) => {
|
Object.keys(formData).forEach((key: string) => {
|
||||||
if (['is_captcha','is_site_captcha'].includes(key)) formData[key] = Boolean(Number(data[key]));
|
if (['is_captcha', 'is_site_captcha'].includes(key)) formData[key] = Boolean(Number(data[key]))
|
||||||
else formData[key] = data[key];
|
else formData[key] = data[key]
|
||||||
})
|
})
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
}
|
}
|
||||||
getFormData()
|
getFormData()
|
||||||
|
|
||||||
@ -75,9 +75,9 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
|||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let save = JSON.parse(JSON.stringify(formData));
|
const save = JSON.parse(JSON.stringify(formData))
|
||||||
Object.keys(save).forEach((key)=>{
|
Object.keys(save).forEach((key) => {
|
||||||
if (['is_captcha','is_site_captcha'].includes(key)) save[key] = Number(save[key]);
|
if (['is_captcha', 'is_site_captcha'].includes(key)) save[key] = Number(save[key])
|
||||||
})
|
})
|
||||||
|
|
||||||
setConfigLogin(save).then(() => {
|
setConfigLogin(save).then(() => {
|
||||||
|
|||||||
@ -38,14 +38,14 @@
|
|||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getAgreementList } from '@/app/api/sys'
|
import { getAgreementList } from '@/app/api/sys'
|
||||||
import { useRouter,useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title;
|
const pageName = route.meta.title
|
||||||
|
|
||||||
let agreementTableData = reactive({
|
const agreementTableData = reactive({
|
||||||
loading: true,
|
loading: true,
|
||||||
data: [],
|
data: []
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,10 +53,10 @@ let agreementTableData = reactive({
|
|||||||
*/
|
*/
|
||||||
const loadAgreementList = () => {
|
const loadAgreementList = () => {
|
||||||
agreementTableData.loading = true
|
agreementTableData.loading = true
|
||||||
agreementTableData.data = [];
|
agreementTableData.data = []
|
||||||
getAgreementList().then(res => {
|
getAgreementList().then(res => {
|
||||||
Object.keys(res.data).forEach((key) => {
|
Object.keys(res.data).forEach((key) => {
|
||||||
return agreementTableData.data.push(res.data[key]);
|
return agreementTableData.data.push(res.data[key])
|
||||||
})
|
})
|
||||||
agreementTableData.loading = false
|
agreementTableData.loading = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
@ -37,9 +37,9 @@ import type { FormInstance } from 'element-plus'
|
|||||||
import { getAgreementInfo, editAgreement } from '@/app/api/sys'
|
import { getAgreementInfo, editAgreement } from '@/app/api/sys'
|
||||||
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'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
// const appStore = useAppStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const agreement_key: string = route.query.key || ''
|
const agreement_key: string = route.query.key || ''
|
||||||
@ -65,11 +65,10 @@ const setFormData = async (agreement_key: string = '') => {
|
|||||||
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
|
||||||
}
|
}
|
||||||
if (agreement_key) setFormData(agreement_key)
|
if (agreement_key) setFormData(agreement_key)
|
||||||
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
@ -87,10 +86,10 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const data = formData
|
const data = formData
|
||||||
data.key = formData.agreement_key;
|
data.key = formData.agreement_key
|
||||||
editAgreement(data).then(res => {
|
editAgreement(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
back();
|
back()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|||||||
@ -57,69 +57,66 @@ import { useRoute } from 'vue-router'
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
|
|
||||||
const loading = ref(true),
|
const loading = ref(true)
|
||||||
ruleFormRef = ref<FormInstance>(),
|
const ruleFormRef = ref<FormInstance>()
|
||||||
formData = reactive<Record<string, string | boolean | Array<string> >>({
|
const formData = reactive<Record<string, string | boolean | Array<string> >>({
|
||||||
is_auto_transfer: "0",
|
is_auto_transfer: '0',
|
||||||
is_auto_verify: "0",
|
is_auto_verify: '0',
|
||||||
is_open: "0",
|
is_open: '0',
|
||||||
min: "0.01",
|
min: '0.01',
|
||||||
rate: "0",
|
rate: '0',
|
||||||
transfer_type: []
|
transfer_type: []
|
||||||
});
|
})
|
||||||
const Transfertype = ref<Array<Object>>([])
|
const Transfertype = ref<Array<Object>>([])
|
||||||
|
|
||||||
// 获取会员转账方式
|
// 获取会员转账方式
|
||||||
const getTransfertypeFn = async()=>{
|
const getTransfertypeFn = async () => {
|
||||||
Transfertype.value = await (await getTransfertype()).data
|
Transfertype.value = await (await getTransfertype()).data
|
||||||
}
|
}
|
||||||
getTransfertypeFn()
|
getTransfertypeFn()
|
||||||
|
|
||||||
|
|
||||||
// 获取会员的配置信息
|
// 获取会员的配置信息
|
||||||
const setFormData = async (id: number = 0) => {
|
const setFormData = async (id: number = 0) => {
|
||||||
const data = await (await getCashOutConfig()).data
|
const data = await (await getCashOutConfig()).data
|
||||||
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]
|
||||||
})
|
})
|
||||||
formData.is_open = Boolean(Number(formData.is_open));
|
formData.is_open = Boolean(Number(formData.is_open))
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
}
|
}
|
||||||
setFormData()
|
setFormData()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const minRules = (rule: any, value: any, callback: any) => {
|
const minRules = (rule: any, value: any, callback: any) => {
|
||||||
if (Number(value) < 0.01) {
|
if (Number(value) < 0.01) {
|
||||||
callback(new Error(t('cashWithdrawalAmountHint')))
|
callback(new Error(t('cashWithdrawalAmountHint')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rateRules = (rule: any, value: any, callback: any) => {
|
const rateRules = (rule: any, value: any, callback: any) => {
|
||||||
if (Number(value) > 100 || Number(value) < 0) {
|
if (Number(value) > 100 || Number(value) < 0) {
|
||||||
callback(new Error(t('commissionRatioHint')))
|
callback(new Error(t('commissionRatioHint')))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
min: [
|
min: [
|
||||||
{ validator: minRules, trigger: 'blur' }
|
{ validator: minRules, trigger: 'blur' }
|
||||||
],
|
],
|
||||||
rate: [
|
rate: [
|
||||||
{ validator: rateRules, trigger: 'blur' }
|
{ validator: rateRules, trigger: 'blur' }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const onSave = async (formEl: FormInstance | undefined) => {
|
const onSave = async (formEl: FormInstance | undefined) => {
|
||||||
if (loading.value || !formEl) return
|
if (loading.value || !formEl) return
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let save = {...formData};
|
const save = { ...formData }
|
||||||
save.is_open = Number(save.is_open).toString();
|
save.is_open = Number(save.is_open).toString()
|
||||||
|
|
||||||
setCashOutConfig(save).then(() => {
|
setCashOutConfig(save).then(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@ -66,19 +66,19 @@ const loading = ref(true)
|
|||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
count: 0,
|
count: 0,
|
||||||
create_time:'',
|
create_time: '',
|
||||||
crond_length:'',
|
crond_length: '',
|
||||||
crond_type:'',
|
crond_type: '',
|
||||||
crond_type_name:'',
|
crond_type_name: '',
|
||||||
data:'',
|
data: '',
|
||||||
delete_time:'',
|
delete_time: '',
|
||||||
last_time:'',
|
last_time: '',
|
||||||
next_time:'',
|
next_time: '',
|
||||||
status_desc:'',
|
status_desc: '',
|
||||||
title:'',
|
title: '',
|
||||||
type:'',
|
type: '',
|
||||||
type_name:'',
|
type_name: '',
|
||||||
update_time:''
|
update_time: ''
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ const formRules = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
// const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@ -101,7 +101,6 @@ const setFormData = async (row: any = null) => {
|
|||||||
if (row[key] != undefined) formData[key] = row[key]
|
if (row[key] != undefined) formData[key] = row[key]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
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 { editNoticeStatus } from '@/app/api/notice'
|
// import { editNoticeStatus } from '@/app/api/notice'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
@ -57,7 +57,7 @@ const initialFormData = {
|
|||||||
message_type: '',
|
message_type: '',
|
||||||
name: '',
|
name: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
receiver: '',
|
receiver: ''
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -70,10 +70,10 @@ const formRules = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['complete'])
|
// const emit = defineEmits(['complete'])
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ const initialFormData = {
|
|||||||
title: '',
|
title: '',
|
||||||
type: '',
|
type: '',
|
||||||
sms_id: '',
|
sms_id: '',
|
||||||
content: ''
|
content: ''
|
||||||
}
|
}
|
||||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ const formRules = computed(() => {
|
|||||||
return {
|
return {
|
||||||
sms_id: [
|
sms_id: [
|
||||||
{ required: true, message: t('smsIdPlaceholder'), trigger: 'blur' }
|
{ required: true, message: t('smsIdPlaceholder'), trigger: 'blur' }
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
const data = formData
|
const data = formData
|
||||||
data.status = data.is_sms;
|
data.status = data.is_sms
|
||||||
|
|
||||||
editNotice(data).then(res => {
|
editNotice(data).then(res => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@ -99,13 +99,13 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const setFormData = async (row: any = null) => {
|
const setFormData = async (row: any = null) => {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
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]
|
||||||
if (row.sms && row.sms[key] != undefined) formData[key] = row.sms[key]
|
if (row.sms && row.sms[key] != undefined) formData[key] = row.sms[key]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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