Merge remote-tracking branch 'origin/dev-hjf'
This commit is contained in:
commit
4c8768d490
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="bg-gray-100 min-h-screen">
|
||||
<!-- Category Tabs -->
|
||||
<scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
||||
<!-- <scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
|
||||
:show-scrollbar="false">
|
||||
<view v-for="(tab, index) in tabs" :key="index"
|
||||
class="inline-block px-15 py-5 mr-10 text-sm rounded-full border transition-colors" :class="[
|
||||
@ -11,7 +11,7 @@
|
||||
]" @click="selectCate(tab.value)">
|
||||
{{ tab.name }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</scroll-view> -->
|
||||
|
||||
<!-- List -->
|
||||
<view v-if="loading && list.length === 0" class="loading-container">
|
||||
@ -50,7 +50,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { onLoad, onReachBottom } from "@dcloudio/uni-app";
|
||||
import dayjs from "dayjs";
|
||||
import api from "@/utils/api.js";
|
||||
@ -60,15 +60,149 @@ const env = __VITE_ENV__;
|
||||
const defaultCorpId = env.MP_CORP_ID;
|
||||
|
||||
const corpId = ref("");
|
||||
const enabledIds = ref([]);
|
||||
const tabs = ref([{ name: "全部", value: "" }]);
|
||||
const activeCateId = ref("");
|
||||
|
||||
const allArticles = ref([]);
|
||||
const list = ref([]);
|
||||
const total = ref(0);
|
||||
const page = ref(1);
|
||||
const pageSize = 20;
|
||||
const loading = ref(false);
|
||||
|
||||
const uniqStrings = (items) => {
|
||||
const seen = new Set();
|
||||
const out = [];
|
||||
for (const item of items) {
|
||||
const s = typeof item === "string" ? item.trim() : "";
|
||||
if (!s || seen.has(s)) continue;
|
||||
seen.add(s);
|
||||
out.push(s);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
const parseIdsParam = (raw) => {
|
||||
if (!raw) return [];
|
||||
const text = Array.isArray(raw) ? raw.join(",") : String(raw);
|
||||
const decoded = decodeURIComponent(text);
|
||||
return uniqStrings(decoded.split(","));
|
||||
};
|
||||
|
||||
const getAllTab = () => ({ name: tabs.value?.[0]?.name || "全部", value: "" });
|
||||
|
||||
const getArticleCateIds = (article) => {
|
||||
const ids = [];
|
||||
if (!article) return ids;
|
||||
|
||||
if (Array.isArray(article.cateIds)) ids.push(...article.cateIds);
|
||||
if (typeof article.cateIds === "string") ids.push(article.cateIds);
|
||||
if (typeof article.cateId === "string") ids.push(article.cateId);
|
||||
|
||||
if (typeof article.categoryId === "string") ids.push(article.categoryId);
|
||||
if (Array.isArray(article.categoryIds)) ids.push(...article.categoryIds);
|
||||
if (typeof article.categoryIds === "string") ids.push(article.categoryIds);
|
||||
|
||||
if (Array.isArray(article.cateList)) {
|
||||
ids.push(
|
||||
...article.cateList.map((c) => c?._id || c?.id).filter((v) => typeof v === "string")
|
||||
);
|
||||
}
|
||||
if (article.cate && typeof article.cate === "object") {
|
||||
const v = article.cate._id || article.cate.id;
|
||||
if (typeof v === "string") ids.push(v);
|
||||
}
|
||||
if (typeof article.cate === "string") ids.push(article.cate);
|
||||
|
||||
return uniqStrings(ids);
|
||||
};
|
||||
|
||||
const filteredArticles = computed(() => {
|
||||
const cateId = activeCateId.value;
|
||||
if (!cateId) return allArticles.value;
|
||||
return allArticles.value.filter((article) => getArticleCateIds(article).includes(cateId));
|
||||
});
|
||||
|
||||
const relatedCateIdSet = computed(() => {
|
||||
const set = new Set();
|
||||
for (const article of allArticles.value) {
|
||||
for (const cateId of getArticleCateIds(article)) set.add(cateId);
|
||||
}
|
||||
return set;
|
||||
});
|
||||
|
||||
const refreshList = (reset = false) => {
|
||||
if (reset) {
|
||||
page.value = 1;
|
||||
list.value = [];
|
||||
}
|
||||
|
||||
const rows = filteredArticles.value || [];
|
||||
total.value = rows.length;
|
||||
|
||||
const start = (page.value - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
const slice = rows.slice(start, end);
|
||||
|
||||
if (page.value === 1) list.value = slice;
|
||||
else list.value = [...list.value, ...slice];
|
||||
};
|
||||
|
||||
const loadEnabledArticles = async () => {
|
||||
if (!corpId.value || enabledIds.value.length === 0) {
|
||||
allArticles.value = [];
|
||||
tabs.value = [getAllTab()];
|
||||
refreshList(true);
|
||||
return;
|
||||
}
|
||||
if (loading.value) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const ids = enabledIds.value;
|
||||
const res = await api("getArticleByIds", { corpId: corpId.value, ids: ids.join(",") });
|
||||
const rows = res && Array.isArray(res.list) ? res.list : [];
|
||||
|
||||
const order = new Map(ids.map((id, idx) => [id, idx]));
|
||||
allArticles.value = rows
|
||||
.map((r) => ({
|
||||
...r,
|
||||
time: r?.createTime ? dayjs(r.createTime).format("YYYY-MM-DD") : "",
|
||||
}))
|
||||
.sort((a, b) => (order.get(a?._id) ?? 1e9) - (order.get(b?._id) ?? 1e9));
|
||||
} catch (err) {
|
||||
console.error("loadEnabledArticles failed:", err);
|
||||
allArticles.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const loadTabs = async () => {
|
||||
if (!corpId.value) return;
|
||||
|
||||
const related = relatedCateIdSet.value;
|
||||
if (!related.size) {
|
||||
tabs.value = [getAllTab()];
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await api("getArticleCateList", { corpId: corpId.value });
|
||||
const cates = res && Array.isArray(res.list) ? res.list : [];
|
||||
const visible = cates.filter((c) => related.has(c?._id));
|
||||
|
||||
tabs.value = [
|
||||
getAllTab(),
|
||||
...visible.map((i) => ({ name: i.label || i.name || "", value: i._id })),
|
||||
];
|
||||
} catch (err) {
|
||||
console.error("loadTabs failed:", err);
|
||||
tabs.value = [getAllTab()];
|
||||
}
|
||||
};
|
||||
|
||||
const loadCates = async () => {
|
||||
if (!corpId.value) return;
|
||||
try {
|
||||
@ -118,7 +252,7 @@ const loadList = async (reset = false) => {
|
||||
const selectCate = async (cateId) => {
|
||||
if (activeCateId.value === cateId) return;
|
||||
activeCateId.value = cateId;
|
||||
await loadList(true);
|
||||
refreshList(true);
|
||||
};
|
||||
|
||||
function goToDetail(item) {
|
||||
@ -128,15 +262,18 @@ function goToDetail(item) {
|
||||
|
||||
onLoad(async (options) => {
|
||||
corpId.value = options?.corpId || defaultCorpId || "";
|
||||
await loadCates();
|
||||
await loadList(true);
|
||||
enabledIds.value = parseIdsParam(options?.ids);
|
||||
activeCateId.value = "";
|
||||
await loadEnabledArticles();
|
||||
await loadTabs();
|
||||
refreshList(true);
|
||||
});
|
||||
|
||||
onReachBottom(() => {
|
||||
if (loading.value) return;
|
||||
if (list.value.length >= total.value) return;
|
||||
page.value += 1;
|
||||
loadList(false);
|
||||
refreshList(false);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import api from '@/utils/api';
|
||||
|
||||
const props = defineProps({
|
||||
@ -38,38 +38,52 @@ const props = defineProps({
|
||||
|
||||
const articles = ref([]);
|
||||
const total = ref(0);
|
||||
const page = ref(1);
|
||||
const pageSize = ref(3);
|
||||
const loading = ref(false);
|
||||
const pageSize = 3;
|
||||
|
||||
const qrcode = computed(() => {
|
||||
const qrcodes = props.team && Array.isArray(props.team.qrcodes) ? props.team.qrcodes : [];
|
||||
return qrcodes[0] || {};
|
||||
});
|
||||
|
||||
const articleIds = computed(() => {
|
||||
const configured = qrcode.value && Array.isArray(qrcode.value.articles) ? qrcode.value.articles : [];
|
||||
const ids = configured.map((item) => item?._id).filter((id) => typeof id === "string" && id.trim());
|
||||
return qrcode.value?.enableAnnounce === "YES" ? ids : [];
|
||||
});
|
||||
|
||||
function goToDetail(article) {
|
||||
if (!article?._id) return;
|
||||
uni.navigateTo({ url: `/pages/article/article-detail?id=${article._id}` });
|
||||
}
|
||||
|
||||
const loadArticles = async (reset = false) => {
|
||||
const loadArticles = async () => {
|
||||
const corpId = props.team?.corpId || "";
|
||||
if (!corpId || loading.value) return;
|
||||
if (reset) {
|
||||
page.value = 1;
|
||||
const ids = articleIds.value;
|
||||
|
||||
if (!corpId || ids.length === 0) {
|
||||
articles.value = [];
|
||||
total.value = 0;
|
||||
return;
|
||||
}
|
||||
if (loading.value) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
corpId,
|
||||
page: page.value,
|
||||
pageSize: pageSize.value,
|
||||
enable: true,
|
||||
};
|
||||
const res = await api("getArticleList", params, false);
|
||||
const list = res && Array.isArray(res.list) ? res.list : [];
|
||||
total.value = Number(res?.total) || 0;
|
||||
if (page.value === 1) articles.value = list;
|
||||
else articles.value = [...articles.value, ...list];
|
||||
const res = await api("getArticleByIds", { corpId, ids: ids.join(",") }, false);
|
||||
const rows = res && Array.isArray(res.list) ? res.list : [];
|
||||
|
||||
const order = new Map(ids.map((id, idx) => [id, idx]));
|
||||
const sorted = rows
|
||||
.slice()
|
||||
.sort((a, b) => (order.get(a?._id) ?? 1e9) - (order.get(b?._id) ?? 1e9));
|
||||
|
||||
total.value = sorted.length;
|
||||
articles.value = sorted.slice(0, pageSize);
|
||||
} catch (err) {
|
||||
console.error("loadArticles failed:", err);
|
||||
articles.value = [];
|
||||
total.value = 0;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@ -77,22 +91,20 @@ const loadArticles = async (reset = false) => {
|
||||
|
||||
function toMorePage() {
|
||||
const corpId = props.team?.corpId || "";
|
||||
if (!corpId) return;
|
||||
uni.navigateTo({ url: `/pages/article/article-cate-list?corpId=${corpId}` });
|
||||
const ids = articleIds.value;
|
||||
if (!corpId || ids.length === 0) return;
|
||||
uni.navigateTo({ url: `/pages/article/article-cate-list?corpId=${corpId}&ids=${encodeURIComponent(ids.join(","))}` });
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.team?.corpId,
|
||||
async (corpId) => {
|
||||
if (!corpId) {
|
||||
() => ({ corpId: props.team?.corpId || "", ids: articleIds.value.join(",") }),
|
||||
async ({ corpId, ids }) => {
|
||||
if (!corpId || !ids) {
|
||||
articles.value = [];
|
||||
total.value = 0;
|
||||
page.value = 1;
|
||||
pageSize.value = 3;
|
||||
return;
|
||||
}
|
||||
pageSize.value = 3;
|
||||
await loadArticles(true);
|
||||
await loadArticles();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user