add Notify

This commit is contained in:
Timi
2026-08-21 13:52:52 +08:00
parent 1f37d36901
commit c97913da2d
9 changed files with 803 additions and 28 deletions
+26 -1
View File
@@ -14,7 +14,19 @@
</div> </div>
</template> </template>
<template v-if="navBarStore.customRightVisible || navBarStore.rightIcon || navBarStore.rightText" #right> <template v-if="navBarStore.customRightVisible || navBarStore.rightIcon || navBarStore.rightText" #right>
<div v-if="navBarStore.customRightVisible" id="app-nav-right" class="nav-right-slot" /> <div class="nav-right-slot">
<div v-if="navBarStore.customRightVisible" id="app-nav-right" />
<t-badge
v-else-if="navBarStore.rightIcon && navBarStore.rightBadge !== undefined"
class="badge"
:count="navBarStore.rightBadge"
:max-count="99"
:show-zero="false"
>
<button class="nav-btn" type="button" @click="navBarStore.rightAction?.()">
<t-icon :name="navBarStore.rightIcon" size="1.25rem" />
</button>
</t-badge>
<button <button
v-else-if="navBarStore.rightIcon" v-else-if="navBarStore.rightIcon"
class="nav-btn" class="nav-btn"
@@ -31,6 +43,7 @@
:class="{ clickable: !!navBarStore.rightAction }" :class="{ clickable: !!navBarStore.rightAction }"
@click="navBarStore.rightAction?.()" @click="navBarStore.rightAction?.()"
></span> ></span>
</div>
</template> </template>
</t-navbar> </t-navbar>
<div class="router-view"> <div class="router-view">
@@ -216,6 +229,14 @@ const tabBarHeight = computed(() => {
-webkit-backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
} }
.badge {
:deep(.t-badge__content) {
display: flex;
align-items: center;
}
}
.nav-btn { .nav-btn {
padding: 0; padding: 0;
border: none; border: none;
@@ -243,6 +264,10 @@ const tabBarHeight = computed(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
:deep(.t-badge) {
display: inline-flex;
}
} }
.nav-text { .nav-text {
+235
View File
@@ -0,0 +1,235 @@
<template>
<div v-can="corePermissionCodes.notify.read" class="notify-detail">
<article v-if="detail" class="article">
<header class="header">
<h1 v-text="getSubject(detail)" />
<div class="sender">
发送用户:<span v-text="getSenderName(detail)" />
</div>
<pass-time-label class="time" :timestamp="detail.sendAt" underline />
</header>
<section v-text="detail.data" />
</article>
<t-empty
v-else
:description="isLoading ? '正在加载通知' : '通知不存在'"
/>
</div>
</template>
<script setup lang="ts">
import { NotifyAPI, type NotifyDetail, PassTimeLabel } from "timi-web";
import { DialogPlugin, Toast } from "tdesign-mobile-vue";
import { useNavBarStore } from "@/store/navBarStore";
import { getErrorMessage } from "@/utils/error";
import { corePermissionCodes } from "@/utils/permission";
const route = useRoute();
const router = useRouter();
const navBarStore = useNavBarStore();
defineOptions({
name: "NotifyDetail"
});
// ---------- 通知数据 ----------
const detail = ref<NotifyDetail>();
const isLoading = ref(false);
const isDeleting = ref(false);
let loadToken = 0;
async function loadDetail(): Promise<void> {
const requestToken = loadToken + 1;
loadToken = requestToken;
navBarStore.clearRight();
const detailId = String(route.params.id || "");
if (!detailId) {
detail.value = undefined;
return;
}
detail.value = undefined;
isLoading.value = true;
try {
const result = await NotifyAPI.internalDetail(detailId);
if (requestToken !== loadToken) {
return;
}
detail.value = result;
setDeleteAction();
await markRead(result, requestToken);
} catch (error) {
console.warn("通知详情加载失败", error);
Toast.error("通知详情加载失败");
} finally {
if (requestToken === loadToken) {
isLoading.value = false;
}
}
}
function setDeleteAction(): void {
if (detail.value?.id) {
navBarStore.setRightText("删除", "var(--td-error-color)", confirmDelete);
}
}
async function confirmDelete(): Promise<void> {
const detailId = detail.value?.id;
if (!detailId || isDeleting.value) {
return;
}
const dialog = DialogPlugin.confirm({
title: "删除通知",
content: "确定删除这条通知吗?删除后将不再显示。",
cancelBtn: "取消",
confirmBtn: "删除",
onCancel() {
dialog.destroy();
},
async onConfirm() {
dialog.destroy();
await deleteDetail(detailId);
}
});
}
async function deleteDetail(detailId: string): Promise<void> {
if (isDeleting.value) {
return;
}
isDeleting.value = true;
navBarStore.clearRight();
try {
await NotifyAPI.deleteInternal(detailId);
Toast.success("通知已删除");
await router.replace({ name: "NotifyList" });
} catch (error) {
Toast.error(getErrorMessage(error, "通知删除失败"));
setDeleteAction();
} finally {
isDeleting.value = false;
}
}
async function markRead(item: NotifyDetail, requestToken: number): Promise<void> {
if (!item.id || item.readAt) {
return;
}
try {
await NotifyAPI.markInternalRead(item.id);
if (requestToken === loadToken && detail.value) {
detail.value = {
...detail.value,
readAt: Date.now()
};
}
} catch (error) {
console.warn("通知标记已读失败", error);
}
}
// ---------- 展示 ----------
function getSubject(item: NotifyDetail): string {
return item.subject?.trim() || "站内通知";
}
function getSenderName(item: NotifyDetail): string {
return item.fromUser?.nick?.trim() || item.fromUser?.name?.trim() || "系统通知";
}
// ---------- 生命周期 ----------
watch(() => route.params.id, async () => {
await loadDetail();
}, { immediate: true });
onMounted(() => {
navBarStore.clearRight();
});
onUnmounted(() => {
navBarStore.clearRight();
});
</script>
<style scoped lang="less">
.notify-detail {
gap: 1rem;
min-height: 100%;
padding: calc(var(--app-nav-height) + 1rem) 0 1rem 0;
display: flex;
flex-direction: column;
.article {
padding: 1.25rem 1rem;
margin: 0 1rem;
background: rgba(255, 255, 255, .92);
box-shadow: var(--td-shadow-1);
border-radius: 1.4rem;
}
.header {
text-align: center;
border-bottom: 1px solid rgba(148, 163, 184, .2);
padding-bottom: 1rem;
h1 {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
.time {
color: #64748b;
margin-top: .5rem;
font-size: .8125rem;
}
.sender {
color: #64748b;
margin-top: .5rem;
font-size: .8125rem;
}
}
.body {
color: #334155;
padding-top: 1rem;
font-size: .9375rem;
line-height: 1.8;
white-space: pre-wrap;
word-break: break-word;
}
}
:global(html.theme-dark) {
.notify-detail {
.article {
background: rgba(15, 23, 42, .88);
box-shadow: 0 .75rem 2rem rgba(2, 6, 23, .32);
}
.header {
border-bottom-color: rgba(148, 163, 184, .16);
.time {
color: #94a3b8;
}
.sender {
color: #94a3b8;
}
}
.body {
color: #cbd5e1;
}
}
}
</style>
+432
View File
@@ -0,0 +1,432 @@
<template>
<div v-can="corePermissionCodes.notify.read" class="notify-list">
<t-segmented
v-model="filterMode"
class="filter"
block
:options="filterOptions"
@change="switchFilter"
/>
<t-pull-down-refresh
v-model="isRefreshing"
:refresh-timeout="30000"
@refresh="refresh"
@scrolltolower="loadMore"
>
<t-cell-group v-if="pageResult.list.length" class="items" theme="card">
<t-swipe-cell
v-for="item in pageResult.list"
:key="item.id"
class="item"
>
<t-cell
:description="getPreview(item)"
:note="getTime(item)"
arrow
hover
@click="toDetail(item)"
>
<template #leftIcon>
<div class="icon" :class="{ unread: isUnread(item) }">
<t-icon name="notification" size="1.25rem" />
</div>
</template>
<template #title>
<div class="title">
<span v-text="getSubject(item)" />
<t-tag
v-if="isUnread(item)"
class="unread-label"
theme="danger"
size="small"
>未读</t-tag>
</div>
</template>
</t-cell>
<template #right>
<t-button
class="delete"
theme="danger"
:loading="deletingId === item.id"
@click.stop="confirmDelete(item)"
>
删除
</t-button>
</template>
</t-swipe-cell>
</t-cell-group>
<t-empty
v-else-if="!isLoading"
description="暂无站内通知"
/>
<div class="load-state" v-text="loadStateText" />
</t-pull-down-refresh>
</div>
</template>
<script setup lang="ts">
import { NotifyAPI, Time, type NotifyDetail, type Page, type PageResult, useUserStore } from "timi-web";
import { DialogPlugin, Toast } from "tdesign-mobile-vue";
import { useNavBarStore } from "@/store/navBarStore";
import { getErrorMessage } from "@/utils/error";
import { corePermissionCodes } from "@/utils/permission";
type NotifyFilter = "all" | "unread";
defineOptions({
name: "NotifyList"
});
const pageSize = 20;
const router = useRouter();
const navBarStore = useNavBarStore();
const userStore = useUserStore();
const canReadNotify = computed(() => userStore.hasPermissions(corePermissionCodes.notify.read));
// ---------- 筛选 ----------
const filterMode = ref<NotifyFilter>("all");
const unreadCount = ref(0);
const unreadTabLabel = computed(() => 0 < unreadCount.value ? `未读 ${unreadCount.value}` : "未读");
const filterOptions = computed(() => [
{ value: "all" as NotifyFilter, label: "全部" },
{ value: "unread" as NotifyFilter, label: unreadTabLabel.value }
]);
// ---------- 列表分页 ----------
const isRefreshing = ref(false);
const isLoading = ref(false);
const isNoMore = ref(false);
const page = reactive<Page<NotifyDetail>>({
index: 0,
size: pageSize
});
const pageResult = reactive<PageResult<NotifyDetail>>({
total: 0,
list: []
});
let loadToken = 0;
let loadingPromise: Promise<void> | undefined;
let isPageActive = true;
const loadStateText = computed(() => {
if (isLoading.value) {
return "正在加载通知";
}
if (isNoMore.value) {
return pageResult.list.length ? "没有更多通知" : "";
}
return "上拉加载更多";
});
async function fetchPage(requestToken: number): Promise<void> {
isLoading.value = true;
const result = await NotifyAPI.listInternal(page, filterMode.value === "unread");
if (requestToken !== loadToken) {
return;
}
pageResult.total = result.total || 0;
pageResult.list = pageResult.list.concat(result.list || []);
page.index += 1;
isNoMore.value = pageResult.list.length >= pageResult.total || (result.list || []).length < page.size;
}
async function loadMore(): Promise<void> {
if (loadingPromise) {
await loadingPromise;
return;
}
if (isNoMore.value) {
return;
}
const requestToken = loadToken;
const request = (async () => {
try {
await fetchPage(requestToken);
} finally {
if (requestToken === loadToken) {
isLoading.value = false;
}
}
})();
loadingPromise = request;
try {
await request;
} finally {
if (loadingPromise === request) {
loadingPromise = undefined;
}
}
}
async function reloadList(): Promise<void> {
const requestToken = loadToken + 1;
loadToken = requestToken;
page.index = 0;
pageResult.total = 0;
pageResult.list = [];
isNoMore.value = false;
if (loadingPromise) {
await loadingPromise;
}
if (requestToken === loadToken) {
await loadMore();
}
}
async function refresh(): Promise<void> {
isRefreshing.value = true;
try {
await reloadList();
await loadUnreadCount();
} finally {
isRefreshing.value = false;
}
}
// ---------- 操作 ----------
const isMarkingAllRead = ref(false);
const deletingId = ref("");
async function loadUnreadCount(): Promise<void> {
try {
unreadCount.value = Math.max(0, await NotifyAPI.countUnreadInternal());
} catch (error) {
unreadCount.value = 0;
console.warn("未读通知数量加载失败", error);
} finally {
updateNavBarAction();
}
}
async function switchFilter(context: { value: string | number }): Promise<void> {
const nextFilter = String(context.value) as NotifyFilter;
if (nextFilter !== "all" && nextFilter !== "unread") {
return;
}
filterMode.value = nextFilter;
await reloadList();
}
async function markAllRead(): Promise<void> {
if (isMarkingAllRead.value || unreadCount.value === 0) {
return;
}
isMarkingAllRead.value = true;
try {
await NotifyAPI.markAllInternalRead();
unreadCount.value = 0;
await reloadList();
Toast.success("已全部标记为已读");
} catch (error) {
console.warn("全部通知标记已读失败", error);
Toast.error("全部标记已读失败");
} finally {
isMarkingAllRead.value = false;
updateNavBarAction();
}
}
async function confirmDelete(item: NotifyDetail): Promise<void> {
if (!item.id || deletingId.value) {
return;
}
const detailId = item.id;
const dialog = DialogPlugin.confirm({
title: "删除通知",
content: "确定删除这条通知吗?删除后将不再显示。",
cancelBtn: "取消",
confirmBtn: "删除",
onCancel() {
dialog.destroy();
},
async onConfirm() {
dialog.destroy();
await deleteNotification(detailId);
}
});
}
async function deleteNotification(detailId: string): Promise<void> {
if (deletingId.value) {
return;
}
deletingId.value = detailId;
try {
await NotifyAPI.deleteInternal(detailId);
await reloadList();
await loadUnreadCount();
Toast.success("通知已删除");
} catch (error) {
Toast.error(getErrorMessage(error, "通知删除失败"));
} finally {
deletingId.value = "";
}
}
function updateNavBarAction(): void {
if (!isPageActive) {
return;
}
navBarStore.clearRight();
if (0 < unreadCount.value) {
navBarStore.setRightText("全部已读", "var(--td-brand-color)", markAllRead);
}
}
// ---------- 展示和导航 ----------
function isUnread(item: NotifyDetail): boolean {
return !item.readAt;
}
function getSubject(item: NotifyDetail): string {
return item.subject?.trim() || "站内通知";
}
function getPreview(item: NotifyDetail): string {
const text = item.data?.replace(/\s+/g, " ").trim() || "无通知内容";
return 80 < text.length ? `${text.slice(0, 80)}...` : text;
}
function getTime(item: NotifyDetail): string {
return Time.toPassedDateTime(item.createdAt || item.sendAt) || "-";
}
async function toDetail(item: NotifyDetail): Promise<void> {
if (!item.id) {
return;
}
await router.push({
name: "NotifyDetail",
params: { id: item.id }
});
}
// ---------- 生命周期 ----------
onMounted(async () => {
navBarStore.clearRight();
if (!canReadNotify.value) {
return;
}
try {
await reloadList();
await loadUnreadCount();
} catch (error) {
console.warn("站内通知加载失败", error);
Toast.error("站内通知加载失败");
}
});
onUnmounted(() => {
isPageActive = false;
navBarStore.clearRight();
});
</script>
<style scoped lang="less">
.notify-list {
display: flex;
padding: calc(var(--app-nav-height) + 1rem) 0 1rem 0;
min-height: 100%;
flex-direction: column;
.filter {
width: calc(100% - 2rem);
margin: 0 1rem;
}
.items {
overflow: hidden;
padding-top: 1rem;
.item {
.delete {
height: 100%;
padding: 0 1rem;
border-radius: 0;
}
&:last-child {
:deep(.t-cell:after) {
display: none;
}
}
:deep(.t-cell__title) {
flex: 1 1 0;
min-width: 0;
}
:deep(.t-cell__description) {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
:deep(.t-cell__note) {
white-space: nowrap;
}
.icon {
width: 3.5rem;
height: 3.5rem;
color: #64748b;
display: flex;
background: #e2e8f0;
align-items: center;
border-radius: .875rem;
justify-content: center;
&.unread {
color: #0f766e;
background: #ccfbf1;
}
}
.title {
gap: .5rem;
display: flex;
align-items: center;
> span:first-child {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.unread-label {
font-size: .6875rem;
}
}
}
}
:global(html.theme-dark) {
.notify-list {
.icon {
color: #94a3b8;
background: #1e293b;
&.unread {
color: #5eead4;
background: rgba(13, 148, 136, .2);
}
}
.unread-label {
color: #5eead4;
background: rgba(13, 148, 136, .2);
}
}
}
</style>
+37 -2
View File
@@ -14,15 +14,19 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useUserStore } from "timi-web"; import { NotifyAPI, useUserStore } from "timi-web";
import { permissionCodes } from "@/utils/permission"; import { useNavBarStore } from "@/store/navBarStore";
import { corePermissionCodes, permissionCodes } from "@/utils/permission";
defineOptions({ defineOptions({
name: "HomeTab" name: "HomeTab"
}); });
const router = useRouter(); const router = useRouter();
const navBarStore = useNavBarStore();
const userStore = useUserStore(); const userStore = useUserStore();
const unreadNotifyCount = ref(0);
let isPageActive = true;
const entryList = [ const entryList = [
{ {
@@ -56,10 +60,41 @@ const entryList = [
]; ];
const visibleEntryList = computed(() => entryList.filter(item => userStore.hasPermissions(item.permission))); const visibleEntryList = computed(() => entryList.filter(item => userStore.hasPermissions(item.permission)));
const canReadNotify = computed(() => userStore.hasPermissions(corePermissionCodes.notify.read));
async function go(path: string): Promise<void> { async function go(path: string): Promise<void> {
await router.push(path); await router.push(path);
} }
async function goNotifyList(): Promise<void> {
await router.push("/notify");
}
async function loadUnreadNotifyCount(): Promise<void> {
try {
unreadNotifyCount.value = Math.max(0, await NotifyAPI.countUnreadInternal());
} catch (error) {
unreadNotifyCount.value = 0;
console.warn("未读通知数量加载失败", error);
}
if (isPageActive) {
navBarStore.setRightBadge(unreadNotifyCount.value);
}
}
onMounted(async () => {
navBarStore.clearRight();
if (canReadNotify.value) {
navBarStore.setRightIcon("notification", goNotifyList);
navBarStore.setRightBadge(0);
await loadUnreadNotifyCount();
}
});
onUnmounted(() => {
isPageActive = false;
navBarStore.clearRight();
});
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
+3 -1
View File
@@ -11,6 +11,7 @@ import pointRoutes from "@/router/routes/pointRoutes";
import registrationRoutes from "@/router/routes/registrationRoutes"; import registrationRoutes from "@/router/routes/registrationRoutes";
import tabRoutes from "@/router/routes/tabRoutes"; import tabRoutes from "@/router/routes/tabRoutes";
import userRoutes from "@/router/routes/userRoutes"; import userRoutes from "@/router/routes/userRoutes";
import notifyRoutes from "@/router/routes/notifyRoutes";
import { useCurrentStoreStore } from "@/store/currentStoreStore"; import { useCurrentStoreStore } from "@/store/currentStoreStore";
import { useGlobalUIStore } from "@/store/globalUI"; import { useGlobalUIStore } from "@/store/globalUI";
import { gaoRoleCodes } from "@/utils/permission"; import { gaoRoleCodes } from "@/utils/permission";
@@ -25,7 +26,8 @@ const detailRoutes = [
...permissionRoutes, ...permissionRoutes,
...pointRoutes, ...pointRoutes,
...chartRoutes, ...chartRoutes,
...managementAccountRoutes ...managementAccountRoutes,
...notifyRoutes
]; ];
const router = createRouter({ const router = createRouter({
+36
View File
@@ -0,0 +1,36 @@
import type { RouteRecordRaw } from "vue-router";
import NotifyDetail from "@/pages/notify/NotifyDetail.vue";
import NotifyList from "@/pages/notify/NotifyList.vue";
const notifyRoutes: RouteRecordRaw[] = [
{
path: "/notify",
name: "NotifyList",
component: NotifyList,
meta: {
depth: 3,
navBarVisible: true,
navBarCanBack: true,
navBarTitle: "站内通知",
tabBarVisible: false,
bodyBackground: "#F5F5F8",
darkBodyBackground: "#10161f"
}
},
{
path: "/notify/:id",
name: "NotifyDetail",
component: NotifyDetail,
meta: {
depth: 4,
navBarVisible: true,
navBarCanBack: true,
navBarTitle: "通知详情",
tabBarVisible: false,
bodyBackground: "#F5F5F8",
darkBodyBackground: "#10161f"
}
}
];
export default notifyRoutes;
+11
View File
@@ -6,6 +6,7 @@ export const useNavBarStore = defineStore("nav-bar", () => {
const title = ref(""); const title = ref("");
const backTo = ref<string>(); const backTo = ref<string>();
const rightIcon = ref(""); const rightIcon = ref("");
const rightBadge = ref<number>();
const rightText = ref(""); const rightText = ref("");
const rightTextColor = ref(""); const rightTextColor = ref("");
const rightAction = shallowRef<(() => void | Promise<void>) | undefined>(); const rightAction = shallowRef<(() => void | Promise<void>) | undefined>();
@@ -33,6 +34,7 @@ export const useNavBarStore = defineStore("nav-bar", () => {
function setRightIcon(value?: string, action?: () => void | Promise<void>): void { function setRightIcon(value?: string, action?: () => void | Promise<void>): void {
rightIcon.value = value || ""; rightIcon.value = value || "";
rightBadge.value = undefined;
rightAction.value = action; rightAction.value = action;
if (value) { if (value) {
rightText.value = ""; rightText.value = "";
@@ -41,11 +43,16 @@ export const useNavBarStore = defineStore("nav-bar", () => {
} }
} }
function setRightBadge(value?: number): void {
rightBadge.value = value === undefined ? undefined : Math.max(0, value);
}
function setRightText(value?: string, color?: string, action?: () => void | Promise<void>): void { function setRightText(value?: string, color?: string, action?: () => void | Promise<void>): void {
rightText.value = value || ""; rightText.value = value || "";
rightTextColor.value = color || ""; rightTextColor.value = color || "";
rightAction.value = action; rightAction.value = action;
if (value) { if (value) {
rightBadge.value = undefined;
rightIcon.value = ""; rightIcon.value = "";
customRightVisible.value = false; customRightVisible.value = false;
} }
@@ -59,6 +66,7 @@ export const useNavBarStore = defineStore("nav-bar", () => {
customRightVisible.value = value; customRightVisible.value = value;
if (value) { if (value) {
rightIcon.value = ""; rightIcon.value = "";
rightBadge.value = undefined;
rightText.value = ""; rightText.value = "";
rightTextColor.value = ""; rightTextColor.value = "";
rightAction.value = undefined; rightAction.value = undefined;
@@ -67,6 +75,7 @@ export const useNavBarStore = defineStore("nav-bar", () => {
function clearRight(): void { function clearRight(): void {
rightIcon.value = ""; rightIcon.value = "";
rightBadge.value = undefined;
rightText.value = ""; rightText.value = "";
rightTextColor.value = ""; rightTextColor.value = "";
rightAction.value = undefined; rightAction.value = undefined;
@@ -78,6 +87,7 @@ export const useNavBarStore = defineStore("nav-bar", () => {
title, title,
backTo, backTo,
rightIcon, rightIcon,
rightBadge,
rightText, rightText,
rightTextColor, rightTextColor,
rightAction, rightAction,
@@ -88,6 +98,7 @@ export const useNavBarStore = defineStore("nav-bar", () => {
setHeight, setHeight,
setBackTo, setBackTo,
setRightIcon, setRightIcon,
setRightBadge,
setRightText, setRightText,
setCustomTitleVisible, setCustomTitleVisible,
setCustomRightVisible, setCustomRightVisible,
+3
View File
@@ -86,6 +86,9 @@ export const corePermissionCodes = {
create: "CORE:USER_ROLE:CREATE", create: "CORE:USER_ROLE:CREATE",
read: "CORE:USER_ROLE:READ", read: "CORE:USER_ROLE:READ",
delete: "CORE:USER_ROLE:DELETE" delete: "CORE:USER_ROLE:DELETE"
},
notify: {
read: "CORE:NOTIFY:READ"
} }
} as const; } as const;
+4 -8
View File
@@ -6,13 +6,13 @@ import Components from "unplugin-vue-components/vite";
import { TDesignResolver } from "unplugin-vue-components/resolvers"; import { TDesignResolver } from "unplugin-vue-components/resolvers";
const localTimiWebRoot = fileURLToPath(new URL("../timi-web", import.meta.url)); const localTimiWebRoot = fileURLToPath(new URL("../timi-web", import.meta.url));
const localTimiWebModule = fileURLToPath(new URL("../timi-web/dist/timi-web.mjs", import.meta.url));
const localTimiWebStyle = fileURLToPath(new URL("../timi-web/dist/timi-web.css", import.meta.url));
const projectRoot = fileURLToPath(new URL(".", import.meta.url)); const projectRoot = fileURLToPath(new URL(".", import.meta.url));
export default defineConfig(({ mode }) => { export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), ""); const env = loadEnv(mode, process.cwd(), "");
const useLocalTimiWeb = env.VITE_USE_LOCAL_TIMI_WEB !== "false"; const useLocalTimiWeb = env.VITE_USE_LOCAL_TIMI_WEB !== "false";
const useLocalTimiWebSource = useLocalTimiWeb && mode === "development";
const useLocalTimiWebPublish = useLocalTimiWeb && mode !== "development";
return { return {
resolve: { resolve: {
dedupe: ["vue", "pinia", "vue-router"], dedupe: ["vue", "pinia", "vue-router"],
@@ -25,15 +25,11 @@ export default defineConfig(({ mode }) => {
? [ ? [
{ {
find: /^timi-web$/, find: /^timi-web$/,
replacement: useLocalTimiWebSource replacement: localTimiWebModule
? fileURLToPath(new URL("../timi-web/src/index.ts", import.meta.url))
: fileURLToPath(new URL("../timi-web/dist/timi-web.mjs", import.meta.url))
}, },
{ {
find: /^timi-web\/style\.css$/, find: /^timi-web\/style\.css$/,
replacement: useLocalTimiWebPublish replacement: localTimiWebStyle
? fileURLToPath(new URL("../timi-web/dist/timi-web.css", import.meta.url))
: fileURLToPath(new URL("../timi-web/src/assets/style/timi-web.less", import.meta.url))
} }
] ]
: []) : [])