feat(app): 基石应用删除解禁——MyConfirm 同步 projman 删除模(输名确认+红色确认键),删除一律危险确认;基石模块/推送仍置灰
build / build (push) Successful in 3m47s
build / build (push) Successful in 3m47s
This commit is contained in:
@@ -1,26 +1,36 @@
|
||||
<template>
|
||||
<Modal v-model="isModal" @on-visible-change="showChange" :title="title">
|
||||
<!-- 确认框固定最高层:可能从任意 transfer 弹窗/抽屉(含手动抬层的 3000 抽屉)里唤起,
|
||||
而 Modal 默认层级是全局计数器 1000+N,会被高 z-index 抽屉盖住 -->
|
||||
<Modal v-model="isModal" @on-visible-change="showChange" :title="title" :z-index="4000" transfer>
|
||||
<Alert type="warning" class="mb-1" show-icon>
|
||||
<template #icon>
|
||||
<Icon type="ios-bulb-outline" :class="{ 'mt-5': !info }" slot="icon" :size="28"></Icon>
|
||||
<Icon type="ios-bulb-outline" :class="{ 'mt-5': !info }" :size="28"></Icon>
|
||||
</template>
|
||||
<div v-if="msg" :class="['message-box', info ? '' : 'mt-10 mb-10 ml-10']">{{ msg }}</div>
|
||||
<template #desc v-if="info" slot="desc">{{ info }}</template>
|
||||
<template #desc v-if="info">{{ info }}</template>
|
||||
</Alert>
|
||||
<div v-if="confirmName" class="confirm-name-block mb-1">
|
||||
<div class="mb-5">
|
||||
此操作<span style="font-weight: bold">无法</span>被回滚。<br />
|
||||
请输入 <span class="confirm-name-text">{{ confirmName }}</span> 以确认:
|
||||
</div>
|
||||
<Input v-model="inputName" placeholder="请输入名称以确认" @on-enter="onOkClick" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<Button type="primary" :loading="okLoading" @click="onOkClick">{{ confirmText }}</Button>
|
||||
<Button :type="danger ? 'error' : 'primary'" :disabled="!nameMatched" :loading="okLoading" @click="onOkClick">{{ confirmText }}</Button>
|
||||
<Button :loading="cancleLoading" @click="onCancleClick">{{ closeText }}</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { Modal, Button, Alert, Icon } from "view-ui-plus";
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import { Modal, Button, Alert, Icon, Input } from "view-ui-plus";
|
||||
|
||||
const isModal = ref(false),
|
||||
okLoading = ref(false),
|
||||
cancleLoading = ref(false);
|
||||
cancleLoading = ref(false),
|
||||
inputName = ref("");
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -30,6 +40,8 @@ const props = withDefaults(
|
||||
isLoading?: boolean;
|
||||
confirmText?: string;
|
||||
closeText?: string;
|
||||
confirmName?: string;
|
||||
danger?: boolean;
|
||||
confirmFn: any;
|
||||
closeFn: any;
|
||||
destroy: Function;
|
||||
@@ -39,9 +51,13 @@ const props = withDefaults(
|
||||
isLoading: true,
|
||||
confirmText: "确认",
|
||||
closeText: "取消",
|
||||
confirmName: "",
|
||||
danger: false,
|
||||
}
|
||||
);
|
||||
|
||||
const nameMatched = computed(() => !props.confirmName || inputName.value.trim() === props.confirmName);
|
||||
|
||||
onMounted(function () {
|
||||
setTimeout(() => {
|
||||
isModal.value = true;
|
||||
@@ -49,6 +65,7 @@ onMounted(function () {
|
||||
});
|
||||
|
||||
const onOkClick = async () => {
|
||||
if (!nameMatched.value) return;
|
||||
if (!!props.isLoading) okLoading.value = true;
|
||||
const { onOk, reslove } = props.confirmFn;
|
||||
await Promise.resolve(onOk());
|
||||
@@ -73,4 +90,15 @@ const showChange = (state: boolean) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style lang="scss" scoped>
|
||||
.confirm-name-block {
|
||||
padding: 0 2px;
|
||||
line-height: 1.6;
|
||||
|
||||
.confirm-name-text {
|
||||
color: #ed4014;
|
||||
font-weight: bold;
|
||||
user-select: all;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,8 +2,8 @@ import { MyConfirm } from "@/types/Basics";
|
||||
import confirm from "./Confirm.vue";
|
||||
|
||||
import { createApp } from "vue";
|
||||
export default ({ title, msg, info, confirmText, closeText, isLoading, onOk, onCancel }: MyConfirm) => {
|
||||
return new Promise<boolean>((reslove, reject) => {
|
||||
export default ({ title, msg, info, confirmText, closeText, isLoading, confirmName, danger, onOk, onCancel }: MyConfirm) => {
|
||||
return new Promise<boolean>((reslove, _reject) => {
|
||||
const instance = createApp(confirm, {
|
||||
title,
|
||||
msg,
|
||||
@@ -11,6 +11,8 @@ export default ({ title, msg, info, confirmText, closeText, isLoading, onOk, onC
|
||||
confirmText,
|
||||
closeText,
|
||||
isLoading,
|
||||
confirmName,
|
||||
danger,
|
||||
confirmFn: {
|
||||
onOk,
|
||||
reslove,
|
||||
|
||||
Vendored
+4
@@ -105,6 +105,10 @@ export interface MyConfirm {
|
||||
isLoading?: boolean;
|
||||
confirmText?: string;
|
||||
closeText?: string;
|
||||
/** 输名确认:值与 msg 对象名一致才允许点确认键(危险操作删除模,对齐 projman) */
|
||||
confirmName?: string;
|
||||
/** 红色确认键(危险操作) */
|
||||
danger?: boolean;
|
||||
onOk?: Function;
|
||||
onCancel?: Function;
|
||||
}
|
||||
|
||||
@@ -181,13 +181,14 @@ const columns = [
|
||||
width: 280,
|
||||
render: (h: any, { row }: any) => {
|
||||
// SCHOOL 模式:仅编辑(名称/描述/图标,写学校覆盖表);模块管理/推送设置/删除全部隐藏。
|
||||
// 基石应用(app_nature=BASE)只做身份注册:模块/推送/删除置灰,「编辑」保持可用(密钥轮换入口)
|
||||
// 基石应用(app_nature=BASE)只做身份注册:模块/推送置灰;删除允许——基石也可下线,
|
||||
// 但走「输名确认」删除模(危险确认,与 projman 应用删除同款)。
|
||||
const base = row.appNature === "BASE";
|
||||
const actions = [$utils.operatingTextHandle(h, '编辑', '', () => handleEdit(row))];
|
||||
if (!isSchoolMode.value) {
|
||||
actions.push($utils.operatingTextHandle(h, '模块管理', '', () => goModuleManage(row), base));
|
||||
actions.push($utils.operatingTextHandle(h, '推送设置', '', () => openPushSetting(row), base));
|
||||
actions.push($utils.operatingTextHandle(h, '删除', 'text-error', () => handleDelete(row), base));
|
||||
actions.push($utils.operatingTextHandle(h, '删除', 'text-error', () => handleDelete(row)));
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
@@ -239,18 +240,24 @@ function openSortModal() {
|
||||
sortModalVisible.value = true;
|
||||
}
|
||||
|
||||
/* ---------------- 删除应用 ---------------- */
|
||||
/* ---------------- 删除应用(删除模:输名确认 + 红色确认键,对齐 projman;基石应用同样可删) ---------------- */
|
||||
async function handleDelete(row: any) {
|
||||
const name = row.name || String(row.id);
|
||||
await MyConfirm({
|
||||
msg: `确定删除应用「${row.name || row.id}」吗?`,
|
||||
info: "删除后不可恢复!",
|
||||
title: "删除应用",
|
||||
msg: `确定删除应用「${name}」吗?`,
|
||||
info: "删除后不可恢复,关联就绪资源需手动清理!"
|
||||
+ (row.appNature === "BASE" ? "(基石应用:请先确认无平台组件仍依赖其 appKey 签名身份)" : ""),
|
||||
confirmName: name,
|
||||
danger: true,
|
||||
confirmText: "删除",
|
||||
async onOk() {
|
||||
try {
|
||||
await Apis.AppSettings.deleteApp({ pathParams: { id: row.id } });
|
||||
Message.success('删除成功!');
|
||||
tableRef.value?.reloadData(OperatorEnum.del);
|
||||
} catch (e: any) {
|
||||
console.warn(e?.message || '删除失败');
|
||||
Message.error(e?.message || '删除失败');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user