update admin

This commit is contained in:
全栈小学生 2023-10-23 17:37:13 +08:00
parent 07767b9d4a
commit e1d8c974f1
9 changed files with 421 additions and 241 deletions

View File

@ -75,4 +75,13 @@ export function getAddonInstalltask() {
*/
export function getAddonCloudInstallLog(addon: string) {
return request.get(`addon/cloudinstall/${addon}`)
}
/**
*
* @param addon
* @returns
*/
export function preUninstallCheck(addon: string) {
return request.get(`addon/uninstall/check/${addon}`, { timeout: 30 * 1000 })
}

View File

@ -4,7 +4,7 @@ import request from '@/utils/request'
*
*/
export function getAuthinfo() {
return request.get('niucloud/authinfo')
return request.get('niucloud/authinfo', { showErrorMessage: false })
}
/**

View File

@ -43,5 +43,6 @@
"downloading": "下载中",
"authTips": "云安装需先绑定授权码如果已有授权请先进行绑定没有授权可到niucloud官网购买云服务之后再进行操作",
"toBind": "绑定授权",
"toNiucloud": "去niucloud官网"
"toNiucloud": "去niucloud官网",
"addonUninstall": "插件卸载"
}

View File

@ -55,5 +55,6 @@
"authSecretPlaceholder": "请输入授权秘钥",
"updateCode": "重新绑定",
"notHaveAuth": "还没有授权?去购买",
"authInfoTips": "授权码和授权秘钥可在Niucloud官网我的授权 授权详情中查看"
"authInfoTips": "授权码和授权秘钥可在Niucloud官网我的授权 授权详情中查看",
"addonUninstall": "插件卸载"
}

View File

@ -1,185 +1,207 @@
<template>
<div class="main main-container min-w-[1000px] min-h-[650px]" v-loading="loading">
<el-card class="box-card !border-none" shadow="never" v-if="!loading">
<div class="flex">
<div class="bg-[#F3F6FF] mr-[14px] w-[402px] pt-[30px] pl-[32px] pr-[46px] pb-[60px]">
<div class="flex items-center justify-between">
<span class="text-[20px] text-[#333333]">版本信息</span>
<el-button class="text-[#4C4C4C] w-[78px] h-[32px] !bg-transparent">检测更新</el-button>
</div>
<div class="mt-[30px] flex items-center text-[14px] text-[#797979]">
<span>当前版本</span>
<span class="text-[26px] ml-[15px] mr-[10px] text-[#656668]">1.0.35</span>
<em class="text-[12px]">(当前已是最新版本)</em>
</div>
</div>
<div class="flex-1 flex justify-between items-center bg-[#F3F6FF] pt-[34px] pl-[30px] pr-[60px] pb-[62px]">
<div class="flex flex-col">
<div class="flex flex-wrap items-center">
<p class="text-[20px] text-[#333] mr-[20px]">授权信息</p>
<span class="text-[14px] text-[#666]">{{authinfo.company_name || '--'}}</span>
</div>
<div class="mt-[46px] ml-[40px] flex flex-wrap">
<span class="text-[14px] text-[#797979] mr-[84px]">授权域名<em class="ml-[12px] text-[12px] text-[#222222]">{{authinfo.site_address || '--'}}</em></span>
<span class="text-[14px] flex items-center text-[#797979]">
<span>授权码</span>
<em class="ml-[12px] mr-[10px] text-[12px] text-[#222222]">{{ authinfo.auth_code ? (isCheck ? authinfo.auth_code : hideAuthCode(authinfo.auth_code)) : '--' }}</em>
<el-icon v-if="!isCheck" @click="isCheck = !isCheck" class="text-[12px] cursor-pointer"><View/></el-icon>
<el-icon v-else @click="isCheck = !isCheck" class="text-[12px] cursor-pointer"><Hide /></el-icon>
</span>
</div>
</div>
<div class="flex flex-1 flex-wrap justify-end relative" >
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary" @click="authCodeApproveFn">授权码认证</el-button>
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click" class="mt-[8px]">
<div class="px-[18px] py-[8px]">
<p class="leading-[32px] text-[14px]">您在官方应用市场购买任意一款应用即可获得授权码输入正确授权码认证通过后即可支持在线升级和其它相关服务</p>
<div class="flex justify-end mt-[36px]">
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
<el-button class="w-[100px] !h-[48px]" plain @click="getAuthCodeDialog.hide()">关闭</el-button>
</div>
</div>
<template #reference>
<el-button class="w-[154px] !h-[48px] mt-[8px] !text-[var(--el-color-primary)] hover:!text-[var(--el-color-primary)] !bg-transparent" plain type="primary">如何获取授权码?</el-button>
</template>
</el-popover>
</div>
<el-dialog v-model="authCodeApproveDialog" title="授权码认证" width="400px">
<el-form :model="formData" label-width="0" ref="formRef" :rules="formRules" class="page-form">
<el-card class="box-card !border-none" shadow="never">
<el-form-item prop="auth_code">
<el-input v-model="formData.auth_code" :placeholder="t('authCodePlaceholder')" class="input-width" clearable size="large" />
</el-form-item>
<div class="main main-container min-w-[1000px] min-h-[650px]" v-loading="loading">
<el-card class="box-card !border-none" shadow="never" v-if="!loading">
<div class="flex">
<div class="bg-[#F3F6FF] mr-[14px] w-[402px] pt-[30px] pl-[32px] pr-[46px] pb-[60px]">
<div class="flex items-center justify-between">
<span class="text-[20px] text-[#333333]">版本信息</span>
<el-button class="text-[#4C4C4C] w-[78px] h-[32px] !bg-transparent">检测更新</el-button>
</div>
<div class="mt-[30px] flex items-center text-[14px] text-[#797979]">
<span>当前版本</span>
<span class="text-[26px] ml-[15px] mr-[10px] text-[#656668]">1.0.35</span>
<em class="text-[12px]">(当前已是最新版本)</em>
</div>
</div>
<div class="flex-1 flex justify-between items-center bg-[#F3F6FF] pt-[34px] pl-[30px] pr-[60px] pb-[62px]">
<div class="flex flex-col">
<div class="flex flex-wrap items-center">
<p class="text-[20px] text-[#333] mr-[20px]">授权信息</p>
<span class="text-[14px] text-[#666]">{{ authinfo.company_name || '--' }}</span>
</div>
<div class="mt-[46px] ml-[40px] flex flex-wrap">
<span class="text-[14px] text-[#797979] mr-[84px]">授权域名<em
class="ml-[12px] text-[12px] text-[#222222]">{{ authinfo.site_address || '--'
}}</em></span>
<span class="text-[14px] flex items-center text-[#797979]">
<span>授权码</span>
<em class="ml-[12px] mr-[10px] text-[12px] text-[#222222]">{{ authinfo.auth_code ? (isCheck
?
authinfo.auth_code : hideAuthCode(authinfo.auth_code)) : '--' }}</em>
<el-icon v-if="!isCheck" @click="isCheck = !isCheck" class="text-[12px] cursor-pointer">
<View />
</el-icon>
<el-icon v-else @click="isCheck = !isCheck" class="text-[12px] cursor-pointer">
<Hide />
</el-icon>
</span>
</div>
</div>
<div class="flex flex-1 flex-wrap justify-end relative">
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary"
@click="authCodeApproveFn">授权码认证</el-button>
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click"
class="mt-[8px]">
<div class="px-[18px] py-[8px]">
<p class="leading-[32px] text-[14px]">您在官方应用市场购买任意一款应用即可获得授权码输入正确授权码认证通过后即可支持在线升级和其它相关服务
</p>
<div class="flex justify-end mt-[36px]">
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
<el-button class="w-[100px] !h-[48px]" plain
@click="getAuthCodeDialog.hide()">关闭</el-button>
</div>
</div>
<template #reference>
<el-button
class="w-[154px] !h-[48px] mt-[8px] !text-[var(--el-color-primary)] hover:!text-[var(--el-color-primary)] !bg-transparent"
plain type="primary">如何获取授权码?</el-button>
</template>
</el-popover>
</div>
<el-dialog v-model="authCodeApproveDialog" title="授权码认证" width="400px">
<el-form :model="formData" label-width="0" ref="formRef" :rules="formRules" class="page-form">
<el-card class="box-card !border-none" shadow="never">
<el-form-item prop="auth_code">
<el-input v-model="formData.auth_code" :placeholder="t('authCodePlaceholder')"
class="input-width" clearable size="large" />
</el-form-item>
<div class="mt-[20px]">
<el-form-item prop="auth_secret">
<el-input v-model="formData.auth_secret" clearable :placeholder="t('authSecretPlaceholder')" class="input-width" size="large" />
</el-form-item>
</div>
<div class="mt-[20px]">
<el-form-item prop="auth_secret">
<el-input v-model="formData.auth_secret" clearable
:placeholder="t('authSecretPlaceholder')" class="input-width" size="large" />
</el-form-item>
</div>
<div class="text-sm mt-[10px] text-info">{{ t('authInfoTips') }}</div>
<div class="text-sm mt-[10px] text-info">{{ t('authInfoTips') }}</div>
<div class="mt-[20px]">
<el-button type="primary" class="w-full" size="large" :loading="saveLoading" @click="save(formRef)">{{ t('confirm') }}</el-button>
</div>
<div class="mt-[10px] text-right">
<el-button type="primary" link @click="market">{{ t('notHaveAuth') }}</el-button>
</div>
</el-card>
</el-form>
</el-dialog>
</div>
</div>
</el-card>
</div>
<div class="mt-[20px]">
<el-button type="primary" class="w-full" size="large" :loading="saveLoading"
@click="save(formRef)">{{
t('confirm') }}</el-button>
</div>
<div class="mt-[10px] text-right">
<el-button type="primary" link @click="market">{{ t('notHaveAuth') }}</el-button>
</div>
</el-card>
</el-form>
</el-dialog>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { t } from "@/lang";
import { getAuthinfo, setAuthinfo, getAdminAuthinfo } from "@/app/api/module";
import { FormInstance, FormRules } from "element-plus";
import { useRoute } from "vue-router";
import { reactive, ref } from 'vue'
import { t } from '@/lang'
import { getAuthinfo, setAuthinfo, getAdminAuthinfo } from '@/app/api/module'
import { FormInstance, FormRules } from 'element-plus'
import { useRoute } from 'vue-router'
const route = useRoute();
const pageName = route.meta.title;
const route = useRoute()
const pageName = route.meta.title
let getAuthCodeDialog = ref(null);
let authCodeApproveDialog = ref(false);
let isCheck = ref(false);
const getAuthCodeDialog = ref(null)
const authCodeApproveDialog = ref(false)
const isCheck = ref(false)
const hideAuthCode = (res)=>{
let authCode = JSON.parse(JSON.stringify(res));
let data = authCode.slice(0, authCode.length/2) + authCode.slice(authCode.length/2, authCode.length-1).replace(/./g, '*')
return data
const hideAuthCode = (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, '*')
return data
}
const authCodeApproveFn = ()=>{
authCodeApproveDialog.value = true;
const authCodeApproveFn = () => {
authCodeApproveDialog.value = true
}
const authinfo = ref("");
const loading = ref(true);
const saveLoading = ref(false);
const authinfo = ref('')
const loading = ref(true)
const saveLoading = ref(false)
const checkAppMange = () => {
getAuthinfo()
.then((res) => {
loading.value = false;
if (res.data.data && res.data.data.length != 0) {
authinfo.value = res.data.data;
authCodeApproveDialog.value = false;
}
})
.catch(() => {
loading.value = false;
authCodeApproveDialog.value = false;
});
};
checkAppMange();
getAuthinfo()
.then((res) => {
loading.value = false
if (res.data.data && res.data.data.length != 0) {
authinfo.value = res.data.data
authCodeApproveDialog.value = false
}
})
.catch(() => {
loading.value = false
authCodeApproveDialog.value = false
})
}
checkAppMange()
const formData = reactive<Record<string, string>>({
auth_code: "",
auth_secret: "",
});
const formRef = ref<FormInstance>();
auth_code: '',
auth_secret: ''
})
const formRef = ref<FormInstance>()
//
const formRules = reactive<FormRules>({
auth_code: [
{ required: true, message: t("authCodePlaceholder"), trigger: "blur" },
],
auth_secret: [
{ required: true, message: t("authSecretPlaceholder"), trigger: "blur" },
],
});
auth_code: [
{ required: true, message: t('authCodePlaceholder'), trigger: 'blur' }
],
auth_secret: [
{ required: true, message: t('authSecretPlaceholder'), trigger: 'blur' }
]
})
const save = async (formEl: FormInstance | undefined) => {
if (saveLoading.value || !formEl) return;
if (saveLoading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
saveLoading.value = true;
await formEl.validate(async (valid) => {
if (valid) {
saveLoading.value = true
setAuthinfo(formData)
.then(() => {
saveLoading.value = false;
checkAppMange();
})
.catch(() => {
saveLoading.value = false;
authCodeApproveDialog.value = false;
});
}
});
};
setAuthinfo(formData)
.then(() => {
saveLoading.value = false
checkAppMange()
})
.catch(() => {
saveLoading.value = false
authCodeApproveDialog.value = false
})
}
})
}
const market = () => {
window.open("https://www.niucloud.com/product");
};
window.open('https://www.niucloud.com/product')
}
</script>
<style lang="scss" scoped>
.app-text {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
}
.main {
background-color: var(--el-bg-color-overlay);
background-color: var(--el-bg-color-overlay);
}
em{
font-style:normal
em {
font-style: normal
}
</style>
<style>
.auth-code-dialog .el-overlay{
background-color: transparent;
}
.auth-code-dialog .el-dialog__header{
padding: 0;
}
.auth-code-dialog .el-dialog__body{
padding: 20px 30px;
}
.auth-code-dialog .el-overlay {
background-color: transparent;
}
.auth-code-dialog .el-dialog__header {
padding: 0;
}
.auth-code-dialog .el-dialog__body {
padding: 20px 30px;
}
</style>

View File

@ -310,13 +310,68 @@
</div>
</el-dialog>
<el-dialog v-model="uninstallShowDialog" :title="t('addonUninstall')" width="850px" :close-on-click-modal="false"
:close-on-press-escape="false">
<el-scrollbar max-height="50vh">
<div class="min-h-[150px]">
<div class="bg-[#fff] my-3" v-if="uninstallCheckResult.dir">
<p class="pt-[20px] pl-[20px] ">{{ t('dirPermission') }}</p>
<div class="px-[20px] pt-[10px] text-[14px]">
<el-row class="py-[10px] items table-head-bg pl-[15px] mb-[10px]">
<el-col :span="12">
<span>{{ t('path') }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('demand') }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('status') }}</span>
</el-col>
</el-row>
<el-row class="pb-[10px] items pl-[15px]" v-for="item in uninstallCheckResult.dir.is_readable">
<el-col :span="12">
<span>{{ item.dir }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('readable') }}</span>
</el-col>
<el-col :span="6">
<span v-if="item.status"><el-icon color="green"><Select /></el-icon></span>
<span v-else>
<el-icon color="red">
<CloseBold />
</el-icon>
</span>
</el-col>
</el-row>
<el-row class="pb-[10px] items pl-[15px]" v-for="item in uninstallCheckResult.dir.is_write">
<el-col :span="12">
<span>{{ item.dir }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('write') }}</span>
</el-col>
<el-col :span="6">
<span v-if="item.status"><el-icon color="green"><Select /></el-icon></span>
<span v-else>
<el-icon color="red">
<CloseBold />
</el-icon>
</span>
</el-col>
</el-row>
</div>
</div>
</div>
</el-scrollbar>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, computed, h } from 'vue'
import { t } from '@/lang'
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog } from '@/app/api/addon'
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck } from '@/app/api/addon'
import { downloadVersion, getAuthinfo } from '@/app/api/module'
import { TabsPaneContext, ElMessageBox, ElNotification } from 'element-plus'
import { img } from '@/utils/common'
@ -582,17 +637,30 @@ watch(currAddon, (nval) => {
installCheckResult.value = {}
})
//
const uninstallShowDialog = ref(false)
//
const uninstallCheckResult = ref({})
/**
* 卸载
* @param key
*/
const uninstallAddonFn = (key: string) => {
uninstallAddon({ addon: key }).then(res => {
localListFn()
userStore.getAppList()
loading.value = false
}).catch(() => {
loading.value = false
preUninstallCheck(key).then(({ data }) => {
if (data.is_pass) {
uninstallAddon({ addon: key }).then(res => {
localListFn()
userStore.getAppList()
loading.value = false
}).catch(() => {
loading.value = false
})
} else {
uninstallCheckResult.value = data
uninstallShowDialog.value = true
}
})
}

View File

@ -60,15 +60,14 @@
</div>
</div>
<el-empty class="mx-auto overview-empty" v-if="!localList.installed.length && !loading">
<el-empty class="mx-auto overview-empty" v-if="!localList.installed.length && !loading">
<template #image>
<div class="w-[230px] mx-auto">
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
</div>
</template>
<template #description>
<p class="flex items-center">{{t('installed-empty')}}</p>
<p class="flex items-center">{{ t('installed-empty') }}</p>
</template>
</el-empty>
</div>
@ -131,7 +130,7 @@
</div>
</div>
<el-empty class="mx-auto overview-empty" v-if="!localList.uninstalled.length && !loading">
<el-empty class="mx-auto overview-empty" v-if="!localList.uninstalled.length && !loading">
<template #image>
<div class="w-[230px] mx-auto">
<img src="@/app/assets/images/index/apply_empty.png" class="max-w-full" alt="">
@ -157,16 +156,17 @@
@click="getAddonDetialFn(item)" v-if="showType == 'small'">
<div class="p-3">
<img v-if="item.icon" class="w-[44px] h-[44px] rounded-sm" :src="item.icon" alt="">
<img v-else class="w-[44px] h-[44px] rounded-sm" src="@/app/assets/images/icon-addon.png"
alt="">
<img v-else class="w-[44px] h-[44px] rounded-sm"
src="@/app/assets/images/icon-addon.png" alt="">
</div>
<div class="flex items-center w-[220px] border-b py-3 justify-between">
<div class="flex flex-col">
<span class="text-[14px] truncate w-[160px]">{{ item.title }}</span>
<span class="text-xs text-gray-400 truncate w-[160px] mt-[4px]">{{ item.desc }}</span>
<span class="text-xs text-gray-400 truncate w-[160px] mt-[4px]">{{ item.desc
}}</span>
</div>
<el-button v-if="item.install_info && Object.keys(item.install_info)?.length" size="small"
round class="!text-primary !border-primary !bg-transparent"
<el-button v-if="item.install_info && Object.keys(item.install_info)?.length"
size="small" round class="!text-primary !border-primary !bg-transparent"
@click.stop="uninstallAddonFn(item.key)">{{ t('unload')
}}</el-button>
<el-button v-else-if="item.is_download && item.install_info <= 0" size="small" round
@ -175,14 +175,16 @@
}}</el-button>
<el-button v-else size="small" :loading="downloading == item.key"
:disabled="downloading != ''" round
class="!text-primary !border-primary !bg-transparent" @click.stop="downEvent(item)">{{
class="!text-primary !border-primary !bg-transparent"
@click.stop="downEvent(item)">{{
t('down') }}</el-button>
</div>
</div>
<div class="flex flex-wrap plug-list pb-10 plug-large" v-if="showType == 'large'">
<div class="app-item cursor-pointer mr-4 mt-[20px] pb-2 bg-[#f7f7f7]"
v-for="(item, index) in localList.all" :key="index + 'a'" @click="getAddonDetialFn(item)">
v-for="(item, index) in localList.all" :key="index + 'a'"
@click="getAddonDetialFn(item)">
<div class="flex justify-center items-center">
<img v-if="item.icon && !item.is_download" class="w-[240px] h-[120px]"
:src="img(item.icon)" />
@ -201,8 +203,8 @@
size="small" round class="!text-primary !border-primary !bg-transparent"
@click.stop="uninstallAddonFn(item.key)">{{ t('unload')
}}</el-button>
<el-button v-else-if="item.is_download && item.install_info <= 0" size="small" round
class="!text-primary !border-primary !bg-transparent"
<el-button v-else-if="item.is_download && item.install_info <= 0" size="small"
round class="!text-primary !border-primary !bg-transparent"
@click.stop="installAddonFn(item.key)">{{ t('install')
}}</el-button>
<el-button v-else size="small" round :loading="downloading == item.key"
@ -212,23 +214,30 @@
</div>
</div>
</div>
</div>
</template>
<div v-if="!localList.all.length && !loading && !authinfo" class="mx-auto overview-empty flex flex-col items-center pt-14 pb-6">
</div>
</template>
<div v-if="!localList.all.length && !loading && !authinfo"
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="flex flex-1 flex-wrap justify-center relative" >
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary" @click="authCodeApproveFn">授权码认证</el-button>
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click" class="mt-[8px]">
<div class="flex flex-1 flex-wrap justify-center relative">
<el-button class="w-[154px] !h-[48px] mt-[8px]" type="primary"
@click="authCodeApproveFn">授权码认证</el-button>
<el-popover ref="getAuthCodeDialog" placement="bottom" :width="478" trigger="click"
class="mt-[8px]">
<div class="px-[18px] py-[8px]">
<p class="leading-[32px] text-[14px]">您在官方应用市场购买任意一款应用即可获得授权码输入正确授权码认证通过后即可支持在线升级和其它相关服务</p>
<p class="leading-[32px] text-[14px]">
您在官方应用市场购买任意一款应用即可获得授权码输入正确授权码认证通过后即可支持在线升级和其它相关服务</p>
<div class="flex justify-end mt-[36px]">
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
<el-button class="w-[100px] !h-[48px]" plain @click="getAuthCodeDialog.hide()">关闭</el-button>
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
<el-button class="w-[100px] !h-[48px]" plain
@click="getAuthCodeDialog.hide()">关闭</el-button>
</div>
</div>
<template #reference>
<el-button class="w-[154px] !h-[48px] mt-[8px] !text-[var(--el-color-primary)] hover:!text-[var(--el-color-primary)] !bg-transparent" plain type="primary">如何获取授权码?</el-button>
<el-button
class="w-[154px] !h-[48px] mt-[8px] !text-[var(--el-color-primary)] hover:!text-[var(--el-color-primary)] !bg-transparent"
plain type="primary">如何获取授权码?</el-button>
</template>
</el-popover>
</div>
@ -237,19 +246,23 @@
<el-form :model="formData" label-width="0" ref="formRef" :rules="formRules" class="page-form">
<el-card class="box-card !border-none" shadow="never">
<el-form-item prop="auth_code">
<el-input v-model="formData.auth_code" :placeholder="t('authCodePlaceholder')" class="input-width" clearable size="large" />
<el-input v-model="formData.auth_code" :placeholder="t('authCodePlaceholder')"
class="input-width" clearable size="large" />
</el-form-item>
<div class="mt-[20px]">
<el-form-item prop="auth_secret">
<el-input v-model="formData.auth_secret" clearable :placeholder="t('authSecretPlaceholder')" class="input-width" size="large" />
<el-input v-model="formData.auth_secret" clearable
:placeholder="t('authSecretPlaceholder')" class="input-width"
size="large" />
</el-form-item>
</div>
<div class="text-sm mt-[10px] text-info">{{ t('authInfoTips') }}</div>
<div class="mt-[20px]">
<el-button type="primary" class="w-full" size="large" :loading="saveLoading" @click="save(formRef)">{{ t('confirm') }}</el-button>
<el-button type="primary" class="w-full" size="large" :loading="saveLoading"
@click="save(formRef)">{{ t('confirm') }}</el-button>
</div>
<div class="mt-[10px] text-right">
<el-button type="primary" link @click="market">{{ t('notHaveAuth') }}</el-button>
@ -375,13 +388,68 @@
</div>
</el-dialog>
<el-dialog v-model="uninstallShowDialog" :title="t('addonUninstall')" width="850px" :close-on-click-modal="false"
:close-on-press-escape="false">
<el-scrollbar max-height="50vh">
<div class="min-h-[150px]">
<div class="bg-[#fff] my-3" v-if="uninstallCheckResult.dir">
<p class="pt-[20px] pl-[20px] ">{{ t('dirPermission') }}</p>
<div class="px-[20px] pt-[10px] text-[14px]">
<el-row class="py-[10px] items table-head-bg pl-[15px] mb-[10px]">
<el-col :span="12">
<span>{{ t('path') }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('demand') }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('status') }}</span>
</el-col>
</el-row>
<el-row class="pb-[10px] items pl-[15px]" v-for="item in uninstallCheckResult.dir.is_readable">
<el-col :span="12">
<span>{{ item.dir }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('readable') }}</span>
</el-col>
<el-col :span="6">
<span v-if="item.status"><el-icon color="green"><Select /></el-icon></span>
<span v-else>
<el-icon color="red">
<CloseBold />
</el-icon>
</span>
</el-col>
</el-row>
<el-row class="pb-[10px] items pl-[15px]" v-for="item in uninstallCheckResult.dir.is_write">
<el-col :span="12">
<span>{{ item.dir }}</span>
</el-col>
<el-col :span="6">
<span>{{ t('write') }}</span>
</el-col>
<el-col :span="6">
<span v-if="item.status"><el-icon color="green"><Select /></el-icon></span>
<span v-else>
<el-icon color="red">
<CloseBold />
</el-icon>
</span>
</el-col>
</el-row>
</div>
</div>
</div>
</el-scrollbar>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, computed, h } from 'vue'
import { t } from '@/lang'
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog } from '@/app/api/addon'
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck } from '@/app/api/addon'
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
import { TabsPaneContext, ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus'
import { img } from '@/utils/common'
@ -648,18 +716,30 @@ watch(currAddon, (nval) => {
installCheckResult.value = {}
})
//
const uninstallShowDialog = ref(false)
//
const uninstallCheckResult = ref({})
/**
* 卸载
* @param key
*/
const uninstallAddonFn = (key: string) => {
uninstallAddon({ addon: key }).then(res => {
storage.set({key: 'menuAppStorage', data: ""})
localListFn()
userStore.getAppList()
loading.value = false
}).catch(() => {
loading.value = false
preUninstallCheck(key).then(({ data }) => {
if (data.is_pass) {
uninstallAddon({ addon: key }).then(res => {
localListFn()
userStore.getAppList()
loading.value = false
}).catch(() => {
loading.value = false
})
} else {
uninstallCheckResult.value = data
uninstallShowDialog.value = true
}
})
}
@ -696,62 +776,61 @@ const getAddonDetialFn = (data: AnyObject) => {
}
//
let authCodeApproveDialog = ref(false);
const authinfo = ref("");
let getAuthCodeDialog = ref(null);
const saveLoading = ref(false);
const authCodeApproveDialog = ref(false)
const authinfo = ref('')
const getAuthCodeDialog = ref(null)
const saveLoading = ref(false)
const checkAppMange = () => {
getAuthinfo()
.then((res) => {
if (res.data.data && res.data.data.length != 0) {
authinfo.value = res.data.data;
}
})
.catch(() => {
authCodeApproveDialog.value = false;
});
};
checkAppMange();
const authCodeApproveFn = ()=>{
authCodeApproveDialog.value = true;
getAuthinfo()
.then((res) => {
if (res.data.data && res.data.data.length != 0) {
authinfo.value = res.data.data
}
})
.catch(() => {
authCodeApproveDialog.value = false
})
}
checkAppMange()
const authCodeApproveFn = () => {
authCodeApproveDialog.value = true
}
const formData = reactive<Record<string, string>>({
auth_code: "",
auth_secret: "",
});
const formRef = ref<FormInstance>();
auth_code: '',
auth_secret: ''
})
const formRef = ref<FormInstance>()
//
const formRules = reactive<FormRules>({
auth_code: [
{ required: true, message: t("authCodePlaceholder"), trigger: "blur" },
],
auth_secret: [
{ required: true, message: t("authSecretPlaceholder"), trigger: "blur" },
],
});
auth_code: [
{ required: true, message: t('authCodePlaceholder'), trigger: 'blur' }
],
auth_secret: [
{ required: true, message: t('authSecretPlaceholder'), trigger: 'blur' }
]
})
const save = async (formEl: FormInstance | undefined) => {
if (saveLoading.value || !formEl) return;
if (saveLoading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
saveLoading.value = true;
setAuthinfo(formData)
.then(() => {
saveLoading.value = false;
checkAppMange();
})
.catch(() => {
saveLoading.value = false;
authCodeApproveDialog.value = false;
});
}
});
};
await formEl.validate(async (valid) => {
if (valid) {
saveLoading.value = true
setAuthinfo(formData)
.then(() => {
saveLoading.value = false
checkAppMange()
})
.catch(() => {
saveLoading.value = false
authCodeApproveDialog.value = false
})
}
})
}
const goRouter = () => {
window.open('https://www.niucloud.com/product')

View File

@ -1,7 +1,7 @@
<template>
<el-container class="h-[60px] bg-[#2B303B] flex items-center justify-between px-[15px] text-white">
<div class="flex items-center text-[14px] leading-[1]">
<span class="iconfont icontuodong !text-[24px] mr-[6px]"></span>
<span class="iconfont icontuodong !text-[25px] mr-[6px]"></span>
<span class="cursor-pointer" @click="goAppManage">{{ t('appMarketPlace') }}</span>
<template v-if="app_debug">
<span class="mx-2 text-[#4F5563] mx-[15px]">|</span>

View File

@ -1,7 +1,7 @@
<template>
<el-container class="h-[60px] bg-[#2B303B] flex items-center justify-between px-[15px] text-white">
<div class="flex items-center text-[14px]">
<span class="iconfont icontuodong !text-[24px] mr-[6px]"></span>
<div class="flex items-center text-[14px] leading-[1]">
<span class="iconfont icontuodong !text-[25px] mr-[6px]"></span>
<span class="cursor-pointer" @click="goAppManage">{{ t('appMarketPlace') }}</span>
<template v-if="app_debug">
<span class="mx-2 text-[#4F5563] mx-[15px]">|</span>