add user invite
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<t-dialog
|
||||
v-model:visible="popupVisible"
|
||||
:cancel-btn="null"
|
||||
confirm-btn="生成邀请海报"
|
||||
:close-on-overlay-click="!pickerVisible"
|
||||
:z-index="10000"
|
||||
destroy-on-close
|
||||
@confirm="generateInvite"
|
||||
>
|
||||
<section class="invite-popup">
|
||||
<header class="header">
|
||||
<h2>配置邀请信息</h2>
|
||||
<button class="close" type="button" @click="popupVisible = false">×</button>
|
||||
</header>
|
||||
<t-form class="form" label-align="left">
|
||||
<t-form-item
|
||||
v-if="isGlobalManager"
|
||||
label="目标门店"
|
||||
arrow
|
||||
@click="openPicker('store')"
|
||||
>
|
||||
<span v-text="selectedStoreName" />
|
||||
</t-form-item>
|
||||
<t-form-item
|
||||
label="目标角色"
|
||||
arrow
|
||||
@click="openPicker('role')"
|
||||
>
|
||||
<span v-text="selectedRoleName" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</section>
|
||||
</t-dialog>
|
||||
<t-popup v-model="pickerVisible" placement="bottom" :z-index="11000">
|
||||
<t-picker
|
||||
v-model="pickerValue"
|
||||
:columns="pickerColumns"
|
||||
:title="pickerType === 'role' ? '选择角色' : '选择门店'"
|
||||
@cancel="pickerVisible = false"
|
||||
@confirm="confirmPicker"
|
||||
/>
|
||||
</t-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
import ManagedUserAPI from "@/api/ManagedUserAPI";
|
||||
import { useCurrentStoreStore } from "@/store/currentStoreStore";
|
||||
import { gaoRoleCodes } from "@/utils/permission";
|
||||
import { RoleAPI, useUserStore } from "timi-web";
|
||||
|
||||
defineOptions({ name: "UserInvite" });
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
storeId?: string;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
"update:visible": [value: boolean];
|
||||
}>();
|
||||
const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
const currentStoreStore = useCurrentStoreStore();
|
||||
const isGlobalManager = computed(() => userStore.hasRoles(gaoRoleCodes.globalManager));
|
||||
const popupVisible = computed({
|
||||
get: () => props.visible,
|
||||
set: value => emit("update:visible", value)
|
||||
});
|
||||
const formModel = reactive({ roleId: "", storeId: "" });
|
||||
const roleList = ref<Array<{ id?: string; name?: string; code?: string }>>([]);
|
||||
const isGenerating = ref(false);
|
||||
const isLoaded = ref(false);
|
||||
const roleOptions = computed(() => roleList.value.filter(item => item.id).map(item => ({ label: item.name || item.code || "未命名角色", value: item.id as string })));
|
||||
const storeOptions = computed(() => currentStoreStore.storeList.filter(item => item.id).map(item => ({ label: item.name || item.code || "未命名门店", value: item.id as string })));
|
||||
const selectedRoleName = computed(() => roleOptions.value.find(item => item.value === formModel.roleId)?.label || "请选择角色");
|
||||
const selectedStoreName = computed(() => storeOptions.value.find(item => item.value === formModel.storeId)?.label || "请选择门店");
|
||||
const pickerVisible = ref(false);
|
||||
const pickerType = ref<"role" | "store">("role");
|
||||
const pickerValue = ref<Array<string | number>>([]);
|
||||
const pickerColumns = computed(() => [pickerType.value === "role" ? roleOptions.value : storeOptions.value]);
|
||||
|
||||
async function loadData(): Promise<void> {
|
||||
if (isLoaded.value) {
|
||||
return;
|
||||
}
|
||||
const roleRequest = RoleAPI.manageableList("GAO");
|
||||
if (isGlobalManager.value) {
|
||||
await currentStoreStore.loadStoreList();
|
||||
formModel.storeId = currentStoreStore.storeList.some(item => item.id === props.storeId)
|
||||
? props.storeId || ""
|
||||
: currentStoreStore.currentStoreId;
|
||||
}
|
||||
roleList.value = await roleRequest;
|
||||
if (!isGlobalManager.value) {
|
||||
const store = await currentStoreStore.loadLoginStore();
|
||||
formModel.storeId = store?.id || "";
|
||||
}
|
||||
isLoaded.value = true;
|
||||
}
|
||||
|
||||
function openPicker(type: "role" | "store"): void {
|
||||
pickerType.value = type;
|
||||
pickerValue.value = [type === "role" ? formModel.roleId : formModel.storeId];
|
||||
pickerVisible.value = true;
|
||||
}
|
||||
|
||||
function confirmPicker(): void {
|
||||
const value = String(pickerValue.value[0] || "");
|
||||
if (pickerType.value === "role") {
|
||||
formModel.roleId = value;
|
||||
} else {
|
||||
formModel.storeId = value;
|
||||
}
|
||||
pickerVisible.value = false;
|
||||
}
|
||||
|
||||
async function generateInvite(): Promise<void> {
|
||||
if (!formModel.roleId || (isGlobalManager.value && !formModel.storeId)) {
|
||||
Toast.warning(isGlobalManager.value ? "请选择角色和门店" : "请选择角色");
|
||||
return;
|
||||
}
|
||||
isGenerating.value = true;
|
||||
try {
|
||||
const result = await ManagedUserAPI.invite(isGlobalManager.value ? { roleId: formModel.roleId, storeId: formModel.storeId } : { roleId: formModel.roleId });
|
||||
popupVisible.value = false;
|
||||
await router.push({
|
||||
name: "UserInvitePoster",
|
||||
query: {
|
||||
code: result.code,
|
||||
expireAt: String(result.expireAt),
|
||||
storeName: isGlobalManager.value ? selectedStoreName.value : currentStoreStore.currentStoreName,
|
||||
roleName: selectedRoleName.value
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
isGenerating.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.visible, async visible => {
|
||||
if (!visible) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await loadData();
|
||||
} catch {
|
||||
Toast.error("邀请配置加载失败");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.invite-popup {
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
color: #0f172a;
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.close {
|
||||
border: 0;
|
||||
padding: 0 .25rem;
|
||||
color: #64748b;
|
||||
background: transparent;
|
||||
font-size: 1.75rem;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
margin: 1rem 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
:global(html.theme-dark) .invite-popup {
|
||||
background: #0f172a;
|
||||
|
||||
.header h2 {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user