聆听历史的回响——多源异构数据采集与融合应用综合实践

news/2024/12/16 1:38:01/文章来源:https://www.cnblogs.com/starryship/p/18608993
这个项目属于哪个课程 2024数据采集与融合技术实践
组名、项目简介 组名:scrapy能帮我爬到美味蟹黄堡的秘方吗
项目需求:文物不能很好的融入我们的生活,它们仿佛一具冰冷的尸体躺在博物馆的展示柜中,静静地接受着岁月的侵蚀和尘埃的覆盖。
项目目标:赋予文物新的生命力,让它们“动”起来。通过人工智能技术,为文物创造更加精彩动人的故事,生成曼妙的声音,制作生动震撼的展示视频,让历史以全新的方式触动人心。
技术路线:vue3前端web网站搭建,python flask后端,华为云平台(服务器接口调用),阿里云平台(部分数据存储),kimi背景故事AI生成,百度ai文本转语音,快手可灵ai平台对口型视频生成和通过接口实现视频生成
团队成员学号 曹星才-072208130
张诗悦-052205144
朱佳杰-012202239
黄悦佳-102202142
詹镇壕-102202149
这个项目目标 将静止的文物与现代科技相结合,赋予它们新的生命和表现力。我们通过先进的人工智能技术,让文物“动”起来,呈现出它们沉睡千年的故事与情感。AI将为每件文物创作更加丰富和感人的背景故事,让它们不再只是历史的见证者,而是活生生的叙述者。同时,通过AI生成曼妙的声音,让这些故事更加生动,引人入胜;借助视觉技术,生成精美的展示视频,生动再现文物的诞生过程、文化背景与历史场景。最终,我们希望通过这一系列创新方式,让更多人触及文物的灵魂,感受历史与文化的魅力。
其他参考文献 https://element-plus.org/zh-CN/component/overview.html
https://cn.vuejs.org/guide/introduction
w3school 在线教程
uiverse.io
Apache ECharts
https://docs.qingque.cn/d/home/eZQClW07IFEuX1csc-VejdY2M?identityId=1oEG9JKKMFv#section=h.a6acy8mosh
码云链接(代码已汇总,各小组成员代码不分开放) 前端:综合设计实践——前端 ·2022级数据采集与融合技术 - 码云 - 开源中国
后端:综合设计实践——后端 ·2022级数据采集与融合技术 - 码云 - 开源中国
爬虫:https://gitee.com/jia1666372886/museumspider/tree/master/

一、项目背景

文物不能很好的融入我们的生活,它们仿佛一具冰冷的尸体躺在博物馆的展示柜中,静静地接受着岁月的侵蚀和尘埃的覆盖。那些曾经承载着历史脉络与文化荣光的物品,如今只剩下了沉默的外壳,无法向我们诉说它们曾经的故事。它们被时间的长河淹没,渐渐失去了与我们生活的联系,变成了一个个静止的符号,等待着被无数的目光定格,却难以真正融入现代人的日常。

这些文物或许曾在千百年前激荡起社会的波澜,或许曾是某个伟大文明的象征,但如今它们的存在仿佛和现代世界隔绝了。我们虽然能够从它们的外观上看到历史的痕迹,感受到当时的技艺与智慧,却难以触摸到那段历史背后的人情冷暖、风云变幻。它们不再是生活的一部分,而是被孤立在某个遥远的过去,只是某种文化的遗物。

然而,尽管它们远离了现代的喧嚣,文物依然是人类历史与文化的见证者。每一件文物都有自己独特的生命力,它们承载着前人的思想、情感和智慧。要想让文物重新焕发出活力,我们需要跨越时空的藩篱,用现代科技去唤醒它们沉睡的记忆。通过人工智能、虚拟现实等技术,文物可以不再是冰冷的展品,而是成为我们与过去沟通的桥梁。它们能够重新讲述那个时代的故事,带领我们走进千年之前的世界,让我们重新感受到历史的脉搏和文化的力量。

在这个数字化、智能化的时代,我们不妨通过创新的方式,去打破文物与现代生活之间的隔阂,让这些承载着历史与文明的珍宝重新走进我们的生活,让它们不再只是博物馆里的静物,而是活跃在我们日常的对话和思考之中。

二、项目分工

成员 任务
曹星才 前端页面设计,接口调度与路由跳转逻辑,js代码编写
张诗悦 前端页面设计,web原型设计,css样式与html框架设计
朱佳杰 文物信息爬取
黄悦佳 后端服务器搭建与数据库管理
詹镇壕 后端服务器搭建与api接口编写

三、个人贡献

路由、接口以及相关js代码介绍

(一)路由跳转逻辑

3.1.1 导航栏

导航栏跳转:主页、展示页、列表(管理)页、管理员中心(登陆)页

const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',component: NavigationBar,children: [{ path: '/home', component: Home },{ path: '/exhibit', component: Exhibit },{ path: '/management', component: Management },{ path: '/personal', component: Personal },{ path: '', redirect: '/home' },],},],
})

3.1.2 根据文物id跳转到相应的详细页

        {path: '/artifact/:id', // 路径包含文物的 IDname: 'ArtifactDetail',component: Detail,props: (route) => ({id: route.params.id,}),},

3.1.3 根据文物id跳转到相应的文物修改页

        {path: '/artifactEdit/:id', // 路径包含文物的 IDname: 'ArtifactEdit',component: Add,props: (route) => ({id: route.params.id,name: route.query.name,period: route.query.period,category: route.query.category,parameter: route.query.parameter,material: route.query.material,thumbnail_path: route.query.thumbnail_path,description: route.query.description,}),},

3.1.4 添加页与分析页

        { path: '/add', name:'add',component: Add },{ path: '/analyse', name:'analyse',component: Analyse },

(二)接口介绍

接口地址设计:

const axiosInstance = axios.create({
baseURL: 'http://***.***.***.***:****', //后端地址
timeout: 1000000,
});

3.2.1 获取文物

全部获取:

export const get_artifacts = () => {return axiosInstance.get(`/api/artifacts`)
}

部分获取:

export const get_artifacts2 = async (limit = 20) => {try {const response = await axiosInstance.get(`/api/artifacts`, {params: {limit,}});return response.data; // 返回文物数据} catch (error) {console.error("Error fetching artifacts:", error);throw error;}
};

根据id获取:

export const get_artifacts_by_id = (id) => {return axiosInstance.get(`/api/artifacts/${id}`)
}

根据名字获取:

export const get_artifact_by_name = async (name, limit = 1) => {try {const response = await axiosInstance.get(`/api/artifacts/search`, {params: {name: name,limit,}});return response.data; // 返回文物数据} catch (error) {console.error("Error fetching artifacts:", error);throw error;}
};

调用:

const loading = ref(true)
// 获取文物列表的函数
const fetchArtifacts = async () => {try {const response = await get_artifacts() // 调用获取文物的 API 函数console.log(response)artifactStore.setArtifactData(response.data.data) // 获取全部artifacts.value = artifactStore.$state.artifact // 更新本地的数据} catch (error) {console.error('获取文物列表失败:', error)alert('获取文物列表失败')} finally {loading.value = false // 结束加载状态}
}

3.2.2 添加文物

export const add_artifact = (artifactData) => {// 获取当前存储的 token(例如从 Pinia store 或 localStorage)const accessToken = localStorage.getItem('access_token');  // 或者使用 Pinia store 获取 tokenif (!accessToken) {// 如果没有 token,提示用户登录return Promise.reject(new Error('请先登录'));}// 发送 POST 请求并携带 Authorization headerreturn axiosInstance.post('/api/artifacts', artifactData, {headers: {Authorization: `Bearer ${accessToken}`,  // 将 token 加入请求头},}).then(response => {if (response.status === 201) {console.log('添加文物信息成功');return response.data; // 返回成功的响应数据} else {throw new Error(`添加文物信息失败,状态码:${response.status}`);}}).catch(error => {console.error('添加文物信息请求失败:', error);throw error;});
};

3.2.3 更新文物

export const update_artifact = (id, artifactData) => {// 获取当前存储的 token(例如从 localStorage 或 Pinia)const accessToken = localStorage.getItem('access_token');  // 或者使用 Pinia store 获取 tokenif (!accessToken) {// 如果没有 token,提示用户登录return Promise.reject(new Error('请先登录'));}// 构建请求头const headers = {Authorization: `Bearer ${accessToken}`,  // 将 token 加入请求头};// 发送 PUT 请求以更新文物信息return axiosInstance.put(`/api/artifacts/${id}`, artifactData, {headers: headers,}).then((response) => {if (response.status === 200) {console.log('文物信息更新成功');return response.data;  // 返回响应数据} else {console.error(`更新文物失败,状态码:${response.status}`);throw new Error(`更新文物失败,状态码:${response.status}`);}}).catch((error) => {console.error('更新文物信息失败:', error);throw error;});
};

调用:

const submitForm = async (formEl) => {if (!formEl) returnawait formEl.validate(async (valid, fields) => {if (valid) {if (isEdit.value) {// 更新文物await update_artifact(ruleForm.id, ruleForm)fetchArtifacts()} else {// 添加文物await add_artifact(ruleForm)fetchArtifacts()}// 跳转或显示成功信息router.push('/management')} else {console.log('error submit!', fields)}})
}

3.2.4 删除文物

export const test_delete_artifact = (id) => {// 获取当前存储的 token(例如从 Pinia store)const accessToken = localStorage.getItem('access_token');  // 或者使用 Pinia store 获取 tokenif (!accessToken) {// 如果没有 token,提示用户登录return Promise.reject(new Error('请先登录'));}// 发送 DELETE 请求并携带 Authorization headerreturn axiosInstance.delete(`/api/artifacts/${id}`, {headers: {Authorization: `Bearer ${accessToken}`,  // 将 token 加入请求头},});
};

调用:

const handleDelete = async (id) => {try {await test_delete_artifact(id) // 调用删除函数alert('文物删除成功')// 删除成功后更新界面} catch (error) {alert(error.message) // 显示错误消息(如没有登录)}
}

3.2.5 登陆

export const login = (account, password) => {return axiosInstance.post('/api/users/login', {phone: account,password: password})
}

调用:

const handleLogin = async () => {try {const response = await login(account.value, password.value)if (response.status === 200) {// 获取并存储 JWT 令牌const accessToken = response.data.access_tokenauthStore.setAccessToken(accessToken)ElMessage({message: '登录成功',type: 'success',customClass: 'el-message-success',})}} catch (error) {console.error('登录失败', error)ElMessage({message: '登录失败,请检查账号和密码,如果没有管理员账号请联系平台开发者',type: 'error',})}
}

3.2.6 添加用户交互记录

export const add_user_interaction = (artifactId, interactionType='view') => {// 获取当前存储的 token(例如从 localStorage 或 Pinia store)const accessToken = localStorage.getItem('access_token');  // 或者使用 Pinia store 获取 tokenif (!accessToken) {// 如果没有 token,提示用户登录return Promise.reject(new Error('请先登录'));}// 请求数据const interactionData = {artifact_id: artifactId,interaction_type: interactionType,  // 交互类型,如 'view'};// 发送 POST 请求并携带 Authorization headerreturn axiosInstance.post('/api/interactions', interactionData, {headers: {Authorization: `Bearer ${accessToken}`,  // 将 token 加入请求头},});
};

调用:

const handleAction = async (id_) => {try {// 先记录用户的交互行为await add_user_interaction(id_, 'view') // 'view' 表示查看交互类型console.log(`交互记录已添加,文物 ID: ${id_}`)} catch (error) {console.error('添加交互记录失败:', error.message)} finally {// 然后跳转到文物详情页面router.push({name: 'ArtifactDetail',params: { id: id_ },})}
}

3.2.7 获取交互记录

根据类别获取:

export const get_interactions_count_by_category = async () => {try {const response = await axiosInstance.get('/api/interactions/category/interactions_count');return response.data;  // 返回文物类别交互数量统计的数据} catch (error) {console.error("Error fetching interactions count by category:", error);throw error;  // 抛出错误,供上层处理}
};

调用:

const fetchAndRenderChart = async () => {try {// 获取文物类别统计数据const countData = await get_artifacts_count_by_category()// 提取数据部分const categoryData = countData.dataconsole.log(categoryData)// 格式化数据,转换为图表需要的形式const chartData = categoryData.map((item) => ({value: item.artifact_count,name: item.category,}))// 图表配置const option1 = {title: {text: '各类别数量占比',left: 'center',textStyle: {fontSize: 30,},},tooltip: {trigger: 'item',formatter: '{a} <br/>{b} : {c} ({d}%)',},legend: {top: 'bottom',},toolbox: {show: true,feature: {mark: { show: true },dataView: { show: true, readOnly: false },restore: { show: true },saveAsImage: { show: true },},},series: [{name: 'Percentage!',type: 'pie',radius: [50, 250],center: ['50%', '50%'],roseType: 'area',itemStyle: {borderRadius: 8,},data: chartData, // 动态填充数据},],}// 获取图表 DOM 容器const myChart1 = echarts.init(chart1.value)// 渲染图表myChart1.setOption(option1)} catch (error) {console.error('获取文物类别统计数量失败', error)}
}

获取每个文物的交互记录:

export const get_artifact_interaction_counts = async (limit = 10) => {try {const response = await axiosInstance.get('/api/interactions/count', {params: {limit,  // 设置请求的 limit 参数},});return response.data; // 返回数据} catch (error) {console.error("Error fetching artifact interaction counts:", error);throw error;}
};

调用:

const fetchAndRenderInteractionChart = async () => {try {// 获取文物交互次数数据const interactionData = await get_interactions_count_by_category()console.log('dasdas', interactionData.data)// 格式化数据const artifactIds = interactionData.data.map((item) => item.category) // 文物ID(或者名称)const interactionCounts = interactionData.data.map((item) => item.category_interaction_count) // 交互次数// 图表配置const option2 = {title: {text: '各类别文物热度',left: 'center',textStyle: {fontSize: 30,},},tooltip: {trigger: 'axis',axisPointer: {type: 'shadow',},},toolbox: {show: true,feature: {mark: { show: true },dataView: { show: true, readOnly: false },restore: { show: true },saveAsImage: { show: true },},},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true,},xAxis: [{type: 'category',data: artifactIds, // 更新为从 API 获取的文物 IDaxisTick: {alignWithLabel: true,},},],yAxis: [{type: 'value',},],series: [{name: 'Count',type: 'bar',barWidth: '60%',data: interactionCounts, // 更新为从 API 获取的交互次数},],}// 获取图表 DOM 容器const myChart2 = echarts.init(chart2.value)// 渲染图表myChart2.setOption(option2)} catch (error) {console.error('获取文物统计数量失败', error)}
}

3.2.8 AI接口

AI故事:

export const get_artifact_story_by_id = (id) => {return axiosInstance.get(`/api/ai_story/${id}`)
}

AI语音:

export const generateAudio = async (text) => {try {const response = await axiosInstance.post('/api/tts', {text: text, // 传递需要转换为语音的文本});return response.data.audio_url; // 返回音频的URL} catch (error) {console.error("Error generating audio:", error);throw error; // 抛出错误,便于外部捕获}
};

AI视频:

export const generateVideo = async (imageUrl) => {try {// 构建查询参数const params = {url: imageUrl};// 发送 GET 请求const response = await axiosInstance.get('/api/ai_video', { params });// 检查响应状态if (response.status === 200) {console.log('生成视频测试通过');console.log(response.data); // 输出返回的 JSON 数据return response.data; // 返回视频生成的相关信息} else {console.error(`生成视频信息失败,状态码:${response.status}, 响应内容:${response.data}`);throw new Error(`生成视频信息失败,状态码:${response.status}`);}} catch (error) {console.error('请求错误:', error);throw error; // 抛出错误,便于外部捕获}
};

调用:

const loading = ref(false)
const handleAI = async (id) => {try {ai_button.value=falseloading.value = trueconst response =await get_artifact_story_by_id(id) console.log(response)story.value=response.data.datacompiledMarkdown.value = marked( story.value)if (compiledMarkdown.value) {generateAudioAndPlay();  // 使用 `compiledMarkdown.value`}generateVideoPlay()} catch (error) {alert(error.message) }finally{loading.value = false
v.value=true}
}// 用于存储音频的 URL
const audioUrl = ref(null)
// 用于显示加载状态
const loading2 = ref(false)// 用 ref 创建对音频元素的引用
const audioPlayer = ref(null)// 生成音频并播放
const generateAudioAndPlay = async () => {// 先清除之前的音频 URLaudioUrl.value = nullloading2.value = truetry {// 调用 API 生成音频并获取音频 URLconst url = await generateAudio(extractTextFromHtml(compiledMarkdown.value))// 设置音频 URLaudioUrl.value = url// 使用 ref 引用播放音频if (audioPlayer.value) {audioPlayer.value.play()}} catch (error) {console.error('音频生成失败:', error)alert('音频生成失败,请重试')} finally {loading2.value = false}
}const videoUrl=ref(null)
const loading3=ref(false)
// 生成视频并获取 URL
const generateVideoPlay = async () => {// 先清除之前的音频 URLvideoUrl.value = nullloading3.value = truetry {console.log(artifact.value.thumbnail_path)const videoData = await generateVideo(artifact.value.thumbnail_path); // 示例图片 URLconsole.log("22222",videoData)videoUrl.value = videoData.data; // 假设返回的数据中有 `videoUrl` 字段} catch (error) {console.error('视频生成失败:', error);}finally{
loading3.value=false}
};const extractTextFromHtml = (html) => {console.log(html)const doc = new DOMParser().parseFromString(html, 'text/html');return doc.body.textContent || '';  // 返回纯文本
};

(三)js代码相关

3.3.1 文物筛选

// 筛选的类别
const selectedCategory = ref('')
// const search=ref(false)// 过滤后的文物列表(根据筛选条件)
const filteredArtifacts = computed(() => {return selectedCategory.value? artifacts.value.filter((item) => item.category === selectedCategory.value): artifacts.value})

3.3.2 分析图表初始化

onMounted(() => {// 调用函数来获取数据并渲染图表fetchAndRenderChart()fetchAndRenderInteractionChart()initChart3()
})

3.3.3 页面详细页接收跳转参数

onMounted(() => {const { id } = route.paramsif (id) {isEdit.value = trueformTitle.value = '更新文物'const { name, period, category, parameter, material, thumbnail_path, description } = route.queryruleForm.id = id || ''ruleForm.name = name || ''ruleForm.period = period || ''ruleForm.category = category || ''ruleForm.parameter = parameter || ''ruleForm.material = material || ''ruleForm.description = description || ''ruleForm.thumbnail_path = thumbnail_path || ''}
})

3.3.4 首页轮播图随机播放

const randomArtifacts = computed(() => {const numToSelect = 10 // 选择6个文物return getRandomItems(artifacts.value, numToSelect)
})function getRandomItems(array, num) {const result = []const seenIndexes = new Set()while (result.length < num && result.length < array.length) {const randomIndex = Math.floor(Math.random() * array.length)// 确保索引不重复if (!seenIndexes.has(randomIndex)) {result.push(array[randomIndex])seenIndexes.add(randomIndex)}}return result
}

3.3.5 展示页子组件向父组件传参

import Checkbox from '@/components/Checkbox.vue'// 传世品、革命文物、国史文物、货币、考古发掘品、名族名俗文物、古籍文献、外国文物、艺术品
const sorts = ref([{text: '传世品',isChecked: true,},{text: '货币',isChecked: true,},{text: '艺术品',isChecked: true,},{text: '革命文物',isChecked: true,},{text: '国史文物',isChecked: true,},{text: '考古发掘品',isChecked: true,},{text: '民族民俗文物',isChecked: true,},{text: '古籍文献',isChecked: true,},{text: '外国文物',isChecked: true,},
]);// 父组件传递的更新数据函数
const emit = defineEmits(['categoryChanged'])// 监听复选框变化
const handleCheckboxChange = () => {// 过滤选中的类别const selectedCategories = sorts.value.filter(item => item.isChecked).map(item => item.text).filter(Boolean);  // 过滤掉任何假值,如 undefined 或 null// 发送选中的类别给父组件emit('categoryChanged',selectedCategories);
};onMounted(() => {handleCheckboxChange()
});

3.3.6 监听管理员转换管理员模式

watch(isAdmin, (newVal) => {if (newVal) {router.push({name: 'ArtifactEdit',params: { id: artifact.value.id },query: {name: artifact.value.name,period: artifact.value.period,category: artifact.value.category,parameter: artifact.value.parameter,material: artifact.value.material,thumbnail_path: artifact.value.thumbnail_path,description: artifact.value.description,},})}
})

3.3.7 按钮点击事件及AI事件触发

const handleAI = async (id) => {try {ai_button.value=falseloading.value = trueconst response =await get_artifact_story_by_id(id) console.log(response)story.value=response.data.datacompiledMarkdown.value = marked( story.value)if (compiledMarkdown.value) {generateAudioAndPlay();  // 使用 `compiledMarkdown.value`}generateVideoPlay()} catch (error) {alert(error.message) }finally{loading.value = false
v.value=true}
}

(四)全局变量stores存储

3.4.1 全部文物

export const useArtifactStore = defineStore('artifact', {state: () => ({artifact: JSON.parse(localStorage.getItem('artifactData')) || [], // 从 localStorage 获取数据,如果没有就初始化为空数组}),actions: {setArtifactData(artifact) {console.log("store", artifact);this.artifact = artifact;// 将数据保存到 localStoragelocalStorage.setItem('artifactData', JSON.stringify(this.artifact));console.log("store2", this.artifact);},clearArtifactData() {this.artifact = [];localStorage.removeItem('artifactData'); // 清除缓存},},});

3.4.2 管理员模式全局状态管理

export const useAdminStore = defineStore('admin', {state: () => ({isAdmin: false, // 管理员模式的状态}),actions: {toggleAdminMode() {// console.log('Before toggle:', this.isAdmin);this.isAdmin = !this.isAdmin; // 切换管理员模式状态//   console.log('aaaaa:', this.isAdmin);}}
});export const useAuthStore = defineStore('auth', {state: () => ({accessToken: localStorage.getItem('access_token') || null, // 初始化时从 localStorage 获取令牌(如果存在)}),actions: {setAccessToken(token) {this.accessToken = tokenlocalStorage.setItem('access_token', token)  // 存储到 localStorage},clearAccessToken() {this.accessToken = nulllocalStorage.removeItem('access_token')  // 从 localStorage 删除},},getters: {isAuthenticated: (state) => !!state.accessToken,  // 判断是否登录}
})

四、收获

对我来说,这次实践真是一次宝贵的成长经历。我负责的是前端部分,使用了Vue 3的组合式API,并通过单文件组件进行开发。刚开始时,面临了很多挑战,例如页面跳转不成功、参数无法正确传递到下一页、JS代码编写的难题以及接口请求不正常或返回的参数不对等问题。每一个问题都曾让我感到有些迷茫,但在不断的摸索和调试中,我最终找到了合适的解决方案。

通过这次实践,我不仅学到了更多关于Vue 3的使用技巧,还提升了问题解决能力。学会了如何在Vue中灵活地管理状态和处理异步请求,如何优化页面跳转流程以及如何确保接口的数据传输准确无误;学会了如何与后端顺利的对接;学会了如何协调组员,互帮互助,做好每一步工作。

前端部分是繁琐的,每调整一步都要全局修改探索,在不断摸爬滚打中,我战胜了自己,让自己掌握了更多的专业知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/853570.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KubeWall:一款现代化的 Kubernetes 集群管理工具

以下文章来源于Github爱好者 ,作者KubeWall KubeWall 是一款功能强大的 Kubernetes 多集群管理工具,采用单一二进制文件的简便部署方式,为用户提供直观且易用的 Web 界面,用于高效管理和监控 Kubernetes 集群。为什么选择 KubeWall? KubeWall 致力于简化 Kubernetes 集群的…

【HW系列+技战法】网络监控告警及多角度资产安全加固技战法

一、技战法概述 随着公司的生产业务和网络不断增加建设,企业和组织面临着越来越多的设备、系统。关键节点设备是否采用冗余架构部署,是否存在设备单点故障风险,遭受网络攻击时是否可以及时进行响应等,它们是保障公司运行稳定性和连续性的重要课题。同时,我们还需要对关键设…

多源异构数据采集与融合应用综合实践

综合设计——多源异构数据采集与融合应用综合实践 Recomind荐宝这个作业属于哪个课程 首页 - 2024数据采集与融合技术实践 - 福州大学 - 班级博客 - 博客园组名、项目介绍 组名:超级无迪爬虫高手元始天尊暴龙战士 Recomind荐宝是一款创新型的购物推荐网站,它整合了多源异构数…

综合设计 ——多源异构数据采集与融合应用综合实践

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/组名 超级无迪爬虫高手元始天尊暴龙战士项目介绍 Recomind荐宝是一款创新型的购物推荐网站,整合了多源异构数据与先进的大语言模型技术。无论用户是在寻找时尚服饰、电子产品…

数据采集综合实践

这个项目属于哪个课程 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/组名、项目简介 组名:都给爷爬项目目标:为心理疾病患者进行个性化的音乐疗愈项目需求:市面上大多数音乐软件都需要会员而且存在打榜等现象,不能完全个性化推荐,我们希望我…

2024CSICN长城杯--Crypto--WriteUp

2024CSICN&长城杯--Crypto--WriteUprasnd task: from Crypto.Util.number import getPrime, bytes_to_long from random import randint import osFLAG = os.getenv("FLAG").encode() flag1 = FLAG[:15] flag2 = FLAG[15:]def crypto1():p = getPrime(1024)q = g…

OS笔记

os cpu执行两种性质的程序内核态程序(管态) 用户态程序内核态执行的特权指令包含:I/O指令 中断指令 存取内存中寄存器指令 程序状态字寄存器变更指令和硬件关联的指令(最底层)包含:时钟管理 中断处理 设备驱动运行比较频繁的指令(最底层的上层)包含:进程管理 内存管理 设…

财务知识-会计做账全套流程

财务知识-会计做账全套流程

druid多数据源配置

AOP实现说明 jump数据源注解 DataSource.javaAOP实现 DataSourceAspect.java数据源常量 DataSourceNames.java动态数据源 DynamicDataSource.java动态数据源config DynamicDataSourceConfig.javaDataSource.java package com.saicmotor.carapp.service.bvalue.manage.common.co…

docker pull拉取镜像超时了 ,可以使用Github Action 构建docker镜像 可以构建arm架构 x86架构镜像

首先要有个GitHub账号把这个项目fork到自己账号底下 地址:https://github.com/wukongdaily/DockerTarBuilder fork了之后进入自己的这个项目底下 点击"Actions" 左边可以选择构建镜像的架构 右边输入要构建的镜像名 输入之后点击 ”Run workflow“ 进行构建 在这里…

44. JavaScript之BOM、DOM

1. BOM 1.1 概念 Browser Object Model是指浏览器对象模型,它使 JavaScript 能与浏览器进行交互。 BOM是浏览器提供的API集合,主要用于处理与浏览器环境相关的任务,如窗口管理、导航、cookie、location等。 1.2 window对象 [1]open() 第一个参数是目标网址,第二个参数可以为…

【嵌入式开发】到底什么是指令集?什么是微架构?他们是什么关系?

一、简述 二、指令集 三、微架构及其与指令集的关系? 四、芯片厂、ARM公司和这些指令集、微架构是什么关系? 五、x86和ARM的竞争!一、简述 CPU的设计遵循图灵机的基本设计思想:任何复杂的运算都可以分解为有限个基本指令的组合来完成。这些基本指令比如加、减、乘、与、或、…