feat(资讯): 添加编辑精选功能及相关组件

- 新增 Element Plus UI 库依赖
- 添加编辑精选接口及页面路由
- 实现编辑精选列表展示及搜索功能
- 在资讯页面顶部添加编辑精选入口
- 为编辑精选列表添加分页功能
This commit is contained in:
34701892@qq.com 2025-11-05 16:39:19 +08:00
parent 383db107da
commit 9bbf2c10b3
7 changed files with 242 additions and 21 deletions

164
package-lock.json generated
View File

@ -26,6 +26,7 @@
"clipboard": "^2.0.11",
"dayjs": "^1.11.9",
"echarts": "^5.6.0",
"element-plus": "^2.11.7",
"js-cookie": "^3.0.5",
"js-md5": "^0.8.3",
"pinia": "^2.0.36",
@ -1785,6 +1786,14 @@
"license": "MIT",
"peer": true
},
"node_modules/@ctrl/tinycolor": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
"engines": {
"node": ">=10"
}
},
"node_modules/@dcloudio/types": {
"version": "3.3.3",
"resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.3.3.tgz",
@ -2237,6 +2246,14 @@
"vite": "^4.0.0"
}
},
"node_modules/@element-plus/icons-vue": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
"integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.16.17",
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz",
@ -2567,6 +2584,28 @@
"node": ">=12"
}
},
"node_modules/@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"dependencies": {
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
"integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
"dependencies": {
"@floating-ui/core": "^1.7.3",
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
},
"node_modules/@intlify/core-base": {
"version": "9.1.9",
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.9.tgz",
@ -3898,6 +3937,16 @@
"node": ">= 8"
}
},
"node_modules/@popperjs/core": {
"name": "@sxzz/popperjs-es",
"version": "2.11.7",
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rollup/pluginutils": {
"version": "4.2.1",
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz",
@ -4073,6 +4122,19 @@
"license": "MIT",
"peer": true
},
"node_modules/@types/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA=="
},
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/node": {
"version": "24.0.4",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.0.4.tgz",
@ -4106,6 +4168,11 @@
"license": "MIT",
"peer": true
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
},
"node_modules/@types/yargs": {
"version": "16.0.9",
"resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.9.tgz",
@ -4506,6 +4573,39 @@
}
}
},
"node_modules/@vueuse/core": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@webassemblyjs/ast": {
"version": "1.14.1",
"resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz",
@ -4925,6 +5025,11 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"dev": true
},
"node_modules/async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
@ -5853,9 +5958,9 @@
}
},
"node_modules/dayjs": {
"version": "1.11.9",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz",
"integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA=="
"version": "1.11.19",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="
},
"node_modules/de-indent": {
"version": "1.0.2",
@ -6039,6 +6144,30 @@
"integrity": "sha512-HE43yYdUUiJVjewV2A9EP8o89Kb4AqMKplMQP2IxEPUws1Etu/ZkdsgUDabUZ/WmbP4ZbvJDOcunvbBUPPIfmw==",
"license": "ISC"
},
"node_modules/element-plus": {
"version": "2.11.7",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.11.7.tgz",
"integrity": "sha512-Bh47wuzsqaNBNDkbtlOlZER1cGcOB8GsXp/+C9b95MOrk0wvoHUV4NKKK7xMkfYNFYdYysQ752oMhnExgAL6+g==",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.3.2",
"@floating-ui/dom": "^1.0.1",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"@types/lodash": "^4.17.20",
"@types/lodash-es": "^4.17.12",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.18",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-unified": "^1.0.3",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/emittery": {
"version": "0.8.1",
"resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz",
@ -9635,9 +9764,22 @@
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"node_modules/lodash-unified": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
"integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
"peerDependencies": {
"@types/lodash-es": "*",
"lodash": "*",
"lodash-es": "*"
}
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
@ -9729,6 +9871,11 @@
"node": ">= 0.6"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
"node_modules/merge": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/merge/-/merge-2.1.1.tgz",
@ -9942,6 +10089,11 @@
"node": ">=0.10.0"
}
},
"node_modules/normalize-wheel-es": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
},
"node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",

View File

@ -57,6 +57,7 @@
"clipboard": "^2.0.11",
"dayjs": "^1.11.9",
"echarts": "^5.6.0",
"element-plus": "^2.11.7",
"js-cookie": "^3.0.5",
"js-md5": "^0.8.3",
"pinia": "^2.0.36",

View File

@ -67,3 +67,8 @@ export const searchNews = (data: any) => {
export const getReleaseList = (data: any) => {
return Request.post("/news/top_news_release_h5_d", data);
};
// 编辑精选接口
export const editTopNews = (data: any) => {
return Request.post("/news/top_news_release_h5_d", data);
};

View File

@ -3,12 +3,14 @@ import pinia from "@/stores/index";
import App from "./App.vue";
import uviewPlus from "@/uni_modules/uview-plus";
import "@/assets/fonts/font.css";
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
export function createApp() {
const app = createSSRApp(App);
app.use(pinia).use(uviewPlus);
app.use(ElementPlus)
return {
app,
};

View File

@ -16,6 +16,11 @@
<text class="menu_item">风口概念</text>
<view class="line" v-if="tabIndex == 3"></view>
</view>
<view class="r_menu_item" @click="tabChange(4)">
<text class="menu_item">编辑精选</text>
<view class="line" v-if="tabIndex == 4"></view>
</view>
</view>
<view @click="logout" v-if="Session.get('token')">

View File

@ -45,6 +45,12 @@ onMounted(async () => {
route.query.name,
});
break;
case "4":
layoutName.value = "rank";
uni.navigateTo({
url: "/pages/realtimeInfo/pc/rank?type=" + route.query.type,
});
break;
}
}
});

View File

@ -4,15 +4,24 @@
<view class="content" :style="{ filter: Session.get('token') ? '' : 'blur(5px)' }">
<view class="top_title">
<text class="pageTitle">资讯头条榜</text>
<image src="@/assets/zixun/top20_icon.png" class="title_icon"></image>
<text class="pageTitle" v-if="pageType != 4">资讯头条榜</text>
<text class="pageTitle" v-if="pageType == 4">编辑精选</text>
<image src="@/assets/zixun/top20_icon.png" class="title_icon" v-if="pageType != 4"></image>
<u-input v-if="pageType == 4" placeholder="请输入搜索内容" v-model="form.keyWord" prefixIcon="search"
prefixIconStyle="font-size: 22px;color: #909399"
style="margin-left: 40rpx;margin-top: 5rpx;border-radius: 20rpx;">
<template #suffix>
<u-button @tap="getNewsList" text="搜索" size="mini"></u-button>
</template>
</u-input>
</view>
<view class="line"></view>
<view class="r_list">
<view class="list_item" v-for="(item, index) in newsList" :key="index">
<view class="r_list_item_num">
<view class="r_list_item_num" v-if="pageType != 4">
<view class="list_item_num num1" v-if="index < 3 && index == 0">{{ index + 1 }}</view>
<view class="list_item_num num2" v-else-if="index < 3 && index == 1">{{ index + 1 }}</view>
<view class="list_item_num num3" v-else-if="index < 3 && index == 2">{{ index + 1 }}</view>
@ -26,37 +35,70 @@
<view class="item_bottom">
<view>
<text class="time">{{ item.source }}</text>
<text class="time" style="margin-left: 30rpx">{{ dayjs(item.publish_time).format("YYYY-MM-DD HH:MM:ss") }}</text>
<text class="time" style="margin-left: 30rpx">{{ dayjs(item.publish_time).format("YYYY-MM-DD HH:MM:ss")
}}</text>
</view>
<text class="score">{{ item.news_score }}</text>
<text class="score" v-if="pageType != 4">{{ item.news_score }}</text>
</view>
</view>
</view>
</view>
<div style="width: 100%;display: flex;justify-content: center;"
v-if="pageType == 4 && newsList && newsList.length > 0">
<el-pagination v-model:current-page="currentPage" :page-size="form.size" layout="prev, pager, next"
:total="form.total" @current-change="currentChange" @size-change="sizeChange" />
</div>
</view>
<LoginPopup
:show="LoginShow"
mode="center"
@handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback"
@handlePopupErrorCallback="handlePopupErrorCallback" />
<LoginPopup :show="LoginShow" mode="center" @handlePopupClose="handlePopupClose"
@handlePopupSuccessCallback="handlePopupSuccessCallback" @handlePopupErrorCallback="handlePopupErrorCallback" />
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted, reactive } from "vue";
import PageTop from "@/pages/realtimeInfo/pc/components/PageTop.vue";
import { getTopNews, getTopNewsDay } from "@/api/newsInfo";
import { getTopNewsDay } from "@/api/newsInfo";
import dayjs from "dayjs/esm/index";
import LoginPopup from "@/components/loginPopup/index.vue";
import { Session } from "@/utils/storage";
import { editTopNews } from "@/api/index";
import { useRoute, useRouter } from "vue-router";
const pageSizes = ref([10, 20, 30, 40]);
const form = reactive({
keyWord: "",
page: 1,
size: 10,
total: 10
});
const currentPage = ref(form.page);
const route = useRoute();
const router = useRouter();
const pageType = ref(route.query.type);
const newsList = ref([]);
//
async function getNewsList() {
console.log("🚀 ~ getNewsList ~ pageType.value:", pageType.value)
if (pageType.value == 4) {
//
let { code, data } = await editTopNews({
...form
});
if (code == 200) {
newsList.value = data.list;
form.total = data.total;
}
} else {
//
newsList.value = await getTopNewsDay({});
}
}
function goDetail(item) {
@ -65,6 +107,11 @@ function goDetail(item) {
});
}
function currentChange(page) {
form.page = page;
getNewsList();
}
onMounted(async (e) => {
getNewsList();
@ -168,6 +215,7 @@ const handlePopupErrorCallback = () => {
background: linear-gradient(169deg, #a9c3e3 0%, #92b2e0 100%);
border-radius: 3px;
}
.num3 {
background: linear-gradient(169deg, #f2996e 0%, #f77741 100%);
border-radius: 3px;
@ -193,6 +241,7 @@ const handlePopupErrorCallback = () => {
.item_title:hover {
color: #057cff;
}
.item_title {
font-family: PingFangSC, PingFang SC;
font-weight: bold;
@ -215,6 +264,7 @@ const handlePopupErrorCallback = () => {
justify-content: space-between;
margin-top: 30rpx;
margin-bottom: 10rpx;
.time {
font-family: PingFangSC, PingFang SC;
font-weight: 400;