Python 写生成 应用商店(2025版) 网页 方便收集应用 ,局域网使用
工具【1】:nginx
配置 nginx.conf 文件
server {
listen 8080;
server_name example.com;location / {
root E:/BIT_Soft_2025;
index index.html index.htm;
}# 定义错误页面
error_page 404 /404.html;
location = /40x.html {
}error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
目录结构:

说明:图片目录img 和 根目录 不参与生成,其中主要和常用目录 系统辅助和电脑维护
software_manager.exe 打包出主程序,编号软件数据和下载地址、和生成图版、生成index.html文件 、(PDF、js)文件备用、生成MD 文件是其中一个重要点,文件放在gitee,或其他代码仓库直接访问

software_manager.py
原代码:方便何时改和修改或升级 用
import sys
import os
import json
from pathlib import Path
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QLineEdit, QTableWidget, QTableWidgetItem, QMessageBox, QFileDialog, QTabWidget, QGroupBox, QScrollArea)
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QIcon, QFont, QPixmap, QImage
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.pagesizes import A4
from PIL import Image, ImageDraw, ImageFontclass SoftwareManager(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("应用商店")self.setMinimumSize(1000, 600)# 设置软件图标# 设置窗口图标,这里需要替换为你自己的图标文件路径 icon = QIcon("app.ico") self.setWindowIcon(icon)# 初始化数据self.data_file = 'software_urls.json'self.webHref = {}self.default_url = 'www.ailanzou.com'self.version = "应用商店"# 创建主窗口部件self.main_widget = QWidget()self.setCentralWidget(self.main_widget)# 创建主布局self.main_layout = QVBoxLayout(self.main_widget)# 创建标签页self.tabs = QTabWidget()self.main_layout.addWidget(self.tabs)# 添加标签页self.tabs.addTab(self.create_url_management_tab(), "URL管理")self.tabs.addTab(self.create_generation_tab(), "文件生成")self.tabs.addTab(self.create_icon_generator_tab(), "图标生成")# 加载数据self.load_data()def create_url_management_tab(self):"""创建URL管理标签页"""tab = QWidget()layout = QVBoxLayout(tab)# 创建表格self.table = QTableWidget()self.table.setColumnCount(3)self.table.setHorizontalHeaderLabels(["软件名", "URL", "图片"])self.table.horizontalHeader().setStretchLastSection(True)layout.addWidget(self.table)# 创建编辑区域edit_group = QGroupBox("编辑")edit_layout = QHBoxLayout(edit_group)self.name_edit = QLineEdit()self.url_edit = QLineEdit()self.name_edit.setPlaceholderText("软件名")self.url_edit.setPlaceholderText("URL")edit_layout.addWidget(QLabel("软件名:"))edit_layout.addWidget(self.name_edit)edit_layout.addWidget(QLabel("URL:"))edit_layout.addWidget(self.url_edit)layout.addWidget(edit_group)# 创建预览区域preview_group = QGroupBox("预览")preview_layout = QHBoxLayout(preview_group)# URL预览按钮url_preview = QPushButton("预览URL")url_preview.clicked.connect(self.preview_url)preview_layout.addWidget(url_preview)# 图片预览区域self.image_preview = QLabel()self.image_preview.setMinimumSize(228, 155) # 设置最小大小self.image_preview.setAlignment(Qt.AlignCenter) # 居中对齐self.image_preview.setStyleSheet("border: 1px solid #ccc;") # 添加边框preview_layout.addWidget(self.image_preview)layout.addWidget(preview_group)# 创建按钮button_layout = QHBoxLayout()add_btn = QPushButton("添加")edit_btn = QPushButton("修改")delete_btn = QPushButton("删除")save_btn = QPushButton("保存")add_btn.clicked.connect(self.add_url)edit_btn.clicked.connect(self.edit_url)delete_btn.clicked.connect(self.delete_url)save_btn.clicked.connect(self.save_data)button_layout.addWidget(add_btn)button_layout.addWidget(edit_btn)button_layout.addWidget(delete_btn)button_layout.addWidget(save_btn)layout.addLayout(button_layout)# 连接选择事件self.table.itemSelectionChanged.connect(self.on_selection_changed)return tabdef create_generation_tab(self):"""创建文件生成标签页"""tab = QWidget()layout = QVBoxLayout(tab)# 创建按钮组button_group = QGroupBox("生成选项")button_layout = QVBoxLayout(button_group)html_btn = QPushButton("生成HTML")pdf_btn = QPushButton("生成PDF")js_btn = QPushButton("生成JS")md_btn = QPushButton("生成MD")html_btn.clicked.connect(self.generate_html)pdf_btn.clicked.connect(self.generate_pdf)js_btn.clicked.connect(self.generate_js)md_btn.clicked.connect(self.generate_md)button_layout.addWidget(html_btn)button_layout.addWidget(pdf_btn)button_layout.addWidget(js_btn)button_layout.addWidget(md_btn)layout.addWidget(button_group)# 添加状态显示self.status_label = QLabel("就绪")layout.addWidget(self.status_label)return tabdef create_icon_generator_tab(self):"""创建图标生成标签页"""tab = QWidget()layout = QVBoxLayout(tab)# 创建输入区域input_group = QGroupBox("图标设置")input_layout = QVBoxLayout(input_group)self.icon_name_edit = QLineEdit()self.icon_text_edit = QLineEdit()self.icon_name_edit.setPlaceholderText("图标名称")self.icon_text_edit.setPlaceholderText("图标文字")input_layout.addWidget(QLabel("图标名称:"))input_layout.addWidget(self.icon_name_edit)input_layout.addWidget(QLabel("图标文字:"))input_layout.addWidget(self.icon_text_edit)# 创建生成按钮generate_btn = QPushButton("生成图标")generate_btn.clicked.connect(self.generate_icon)layout.addWidget(input_group)layout.addWidget(generate_btn)return tabdef load_data(self):"""加载数据"""try:if os.path.exists(self.data_file):with open(self.data_file, 'r', encoding='utf-8') as f:data = json.load(f)# 检查数据格式if isinstance(data, dict):self.webHref = dataelse:self.webHref = {}QMessageBox.warning(self, "警告", "JSON文件格式不正确,已重置数据")# 更新表格self.table.setRowCount(len(self.webHref))for row, (name, info) in enumerate(self.webHref.items()):self.table.setItem(row, 0, QTableWidgetItem(name))self.table.setItem(row, 1, QTableWidgetItem(info.get('url', self.default_url)))# 检查img目录中是否存在对应的图片image_path = f'img/{name}.png'image_item = QTableWidgetItem("None" if not os.path.exists(image_path) else image_path)image_item.setFlags(image_item.flags() & ~Qt.ItemIsEditable) # 设置为只读self.table.setItem(row, 2, image_item)except json.JSONDecodeError:QMessageBox.critical(self, "错误", "JSON文件格式错误,请检查文件内容")self.webHref = {}except Exception as e:QMessageBox.critical(self, "错误", f"加载数据时出错:{str(e)}")self.webHref = {}def save_data(self):"""保存数据"""try:# 收集表格中的数据new_data = {}for row in range(self.table.rowCount()):name = self.table.item(row, 0).text()url = self.table.item(row, 1).text()if name and url:new_data[name] = {'url': url}# 保存到JSON文件with open(self.data_file, 'w', encoding='utf-8') as f:json.dump(new_data, f, ensure_ascii=False, indent=4, sort_keys=True)# 更新内存中的数据self.webHref = new_data# 显示成功消息QMessageBox.information(self, "成功", "数据保存成功!")# 自动保存后更新其他文件self.update_generated_files()except Exception as e:QMessageBox.critical(self, "错误", f"保存数据时出错:{str(e)}")def update_generated_files(self):"""更新所有生成的文件"""try:# 更新HTML文件if os.path.exists("index.html"):self.generate_html()# 更新PDF文件if os.path.exists("software.pdf"):self.generate_pdf()# 更新JS文件if os.path.exists("index.js"):self.generate_js()# 更新MD文件if os.path.exists("software.md"):self.generate_md()except Exception as e:QMessageBox.warning(self, "警告", f"更新生成文件时出错:{str(e)}")def add_url(self):"""添加URL"""name = self.name_edit.text().strip()url = self.url_edit.text().strip()if not name or not url:QMessageBox.warning(self, "警告", "软件名和URL都不能为空!")return# 检查是否已存在for row in range(self.table.rowCount()):if self.table.item(row, 0).text() == name:QMessageBox.warning(self, "警告", f"软件名 '{name}' 已存在!")returnrow = self.table.rowCount()self.table.insertRow(row)self.table.setItem(row, 0, QTableWidgetItem(name))self.table.setItem(row, 1, QTableWidgetItem(url))# 检查img目录中是否存在对应的图片image_path = f'img/{name}.png'image_item = QTableWidgetItem("None" if not os.path.exists(image_path) else image_path)image_item.setFlags(image_item.flags() & ~Qt.ItemIsEditable) # 设置为只读self.table.setItem(row, 2, image_item)self.name_edit.clear()self.url_edit.clear()def edit_url(self):"""修改URL"""selected = self.table.selectedItems()if not selected:QMessageBox.warning(self, "警告", "请先选择要修改的项!")returnname = self.name_edit.text().strip()url = self.url_edit.text().strip()if not name or not url:QMessageBox.warning(self, "警告", "软件名和URL都不能为空!")returnrow = selected[0].row()self.table.setItem(row, 0, QTableWidgetItem(name))self.table.setItem(row, 1, QTableWidgetItem(url))# 检查img目录中是否存在对应的图片image_path = f'img/{name}.png'image_item = QTableWidgetItem("None" if not os.path.exists(image_path) else image_path)image_item.setFlags(image_item.flags() & ~Qt.ItemIsEditable) # 设置为只读self.table.setItem(row, 2, image_item)# 更新内存中的数据self.webHref[name] = {'url': url}# 自动保存并更新生成的文件self.save_data()self.name_edit.clear()self.url_edit.clear()def delete_url(self):"""删除URL"""selected = self.table.selectedItems()if not selected:QMessageBox.warning(self, "警告", "请先选择要删除的项!")returnreply = QMessageBox.question(self, "确认", "确定要删除选中的项吗?",QMessageBox.Yes | QMessageBox.No)if reply == QMessageBox.Yes:self.table.removeRow(selected[0].row())def on_selection_changed(self):"""处理表格选择变化功能说明:1. 当用户选择表格中的一行时触发2. 更新编辑框中的软件名和URL3. 更新图片预览区域4. 如果图片存在则显示,不存在则显示"无图片""""selected = self.table.selectedItems()if selected:row = selected[0].row()# 更新编辑框self.name_edit.setText(self.table.item(row, 0).text())self.url_edit.setText(self.table.item(row, 1).text())# 更新图片预览image_path = self.table.item(row, 2).text()if image_path != "None" and os.path.exists(image_path):# 加载图片,不进行缩放pixmap = QPixmap(image_path)self.image_preview.setPixmap(pixmap)# 根据图片大小调整预览区域self.image_preview.setFixedSize(pixmap.size())else:# 清除图片并显示提示文字self.image_preview.clear()self.image_preview.setText("无图片")# 恢复默认大小self.image_preview.setFixedSize(228, 155)def preview_url(self):"""预览URL功能功能说明:1. 获取URL输入框中的内容2. 检查URL是否为空3. 自动添加http://前缀(如果没有)4. 使用默认浏览器打开URL"""url = self.url_edit.text().strip()if not url:QMessageBox.warning(self, "警告", "请输入URL!")return# 检查URL格式if not url.startswith(('http://', 'https://')):url = 'http://' + url# 使用默认浏览器打开URLimport webbrowserwebbrowser.open(url)def generate_html(self):"""生成HTML文件"""try:self.status_label.setText("正在生成HTML...")QApplication.processEvents()with open("index.html", "w", encoding="utf-8") as f:# HTML头部f.write('<!DOCTYPE html>\n<html lang="zh-CHS">\n<head>\n')f.write('<meta charset="UTF-8">\n<meta name="viewport" content="width=device-width, initial-scale=1.0">\n')f.write('<title>应用商店</title>\n')f.write('<link rel="icon" href="img/favicon.ico" type="image/x-icon">\n')f.write('<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon">\n')f.write('<link rel="stylesheet" href="index.css">\n</head>\n<body>\n')# 导航菜单f.write('<div>\n<div class="nav">\n<h3>目录</h3>\n<ul>\n')for root, _, _ in os.walk('.'):dirname = os.path.basename(root)if not dirname or dirname == '.' or dirname == 'img':continuef.write(f'<li><a href="#{dirname}">{dirname}</a></li>\n')f.write('</ul></div>\n')# 内容区域f.write('<div class="course wrapper">\n<br>\n')# 生成软件列表i = 0for root, _, files in os.walk('.'):dirname = os.path.basename(root)if not dirname or dirname == '.' or dirname == 'img':continuei += 1f.write(f'<div class="hd"><h3 id="{dirname}">{dirname}</h3></div>\n')f.write(f'<div class="bd bdx{i}"><ul>\n')for file in files:base_name = self.get_string_before_dash(file)# 获取URL,确保是字符串而不是字典url_info = self.webHref.get(base_name, {})if isinstance(url_info, dict):official_url = url_info.get('url', self.default_url)else:official_url = self.default_url# 检查图片是否存在image_path = f'img/{base_name}.png'image_src = image_path if os.path.exists(image_path) else 'img/test.png'f.write(f'''<li><div class="pic"><img src="{image_src}" onerror="replaceImage(this);"></div><div class="text"><h3>{file}</h3><p><a href="{dirname}/{file}"><span>下载</span></a><a class="{base_name}" href="{official_url}" target="_blank"><strong>外网</strong></a><i>{dirname}</i></p></div></li>\n''')f.write('</ul></div>\n')# HTML尾部f.write('</div>\n</div>\n')f.write('<script>function replaceImage(img) {img.onerror = null;img.src = "img/test.png";}</script>\n')f.write('<script src="index.js"></script>\n')f.write('</body>\n</html>\n')self.status_label.setText("HTML生成完成")QMessageBox.information(self, "成功", "HTML文件生成成功!")except Exception as e:QMessageBox.critical(self, "错误", f"生成HTML时出错:{str(e)}")self.status_label.setText("生成HTML失败")def generate_pdf(self):"""生成PDF文件"""try:self.status_label.setText("正在生成PDF...")QApplication.processEvents()pdf_filename = "software.pdf"c = canvas.Canvas(pdf_filename, pagesize=A4)# 设置中文字体pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))c.setFont('SimSun', 12)y_pos = 790x_pos = 20c.drawString(250, 800, f"{self.version} PDF版")for root, _, files in os.walk('.'):dirname = os.path.basename(root)if not dirname or dirname == '.' or dirname == 'img':continueif y_pos <= 60:c.showPage()c.setFont('SimSun', 12)y_pos = 790c.drawString(x_pos, y_pos, '-' * 40)c.drawString(x_pos, y_pos-7, dirname)c.drawString(x_pos, y_pos-14, '-' * 40)y_pos -= 30for file in files:if y_pos <= 50:c.showPage()c.setFont('SimSun', 12)y_pos = 790base_name = self.get_string_before_dash(file)url = self.webHref.get(base_name, self.default_url)file_info = f"{file[:-4]} --> {url}"c.drawString(x_pos, y_pos, file_info)y_pos -= 15c.save()self.status_label.setText("PDF生成完成")QMessageBox.information(self, "成功", "PDF文件生成成功!")except Exception as e:QMessageBox.critical(self, "错误", f"生成PDF时出错:{str(e)}")self.status_label.setText("生成PDF失败")def generate_js(self):"""生成JS文件"""try:self.status_label.setText("正在生成JS...")QApplication.processEvents()with open("index.js", "w", encoding="utf-8") as f:f.write('// 1. 初始数据\n')f.write('const sliderData = [\n')for root, _, files in os.walk('.'):dirname = os.path.basename(root)if not dirname or dirname == '.' or dirname == 'img':continuefor file in files:base_name = self.get_string_before_dash(file)# 获取URL,确保是字符串而不是字典url_info = self.webHref.get(base_name, {})if isinstance(url_info, dict):url = url_info.get('url', self.default_url)else:url = self.default_urlf.write(f' {{ name:"{base_name}", url:"{url}" }},\n')f.write(']\n\n')f.write('// 1. 获取元素\n')f.write('for(t = 0; t < sliderData.length; t++) {\n')f.write(' let cname = sliderData[t].name\n')f.write(' let a = document.querySelector(`.${cname}`)\n')f.write(' if(a) a.href = sliderData[t].url\n')f.write('}\n')self.status_label.setText("JS生成完成")QMessageBox.information(self, "成功", "JS文件生成成功!")except Exception as e:QMessageBox.critical(self, "错误", f"生成JS时出错:{str(e)}")self.status_label.setText("生成JS失败")def generate_icon(self):"""生成软件图标"""try:name = self.icon_name_edit.text().strip()text = self.icon_text_edit.text().strip()if not name or not text:QMessageBox.warning(self, "警告", "名称和内容都不能为空!")return# 创建一个新的白色背景图片width, height = 228, 155img = Image.new('RGB', (width, height), color=(255, 255, 255))# 创建绘图对象d = ImageDraw.Draw(img)# 绘制背景d.rectangle([0, 0, width, height], fill=(39, 47, 60))# 绘制渐变色条d.rectangle([20, 88, 200, 122], fill=(0, 214, 225))d.rectangle([20, 88, 195, 122], fill=(1, 117, 255))# 添加文字font_path = 'C:/Windows/Fonts/simhei.ttf'font_size = 24font = ImageFont.truetype(font_path, font_size)text_position = (30, 92)d.text(text_position, text, fill=(255, 255, 255), font=font)# 确保保存路径存在save_path = 'img'os.makedirs(save_path, exist_ok=True)# 保存图片full_path = os.path.join(save_path, f'{name}.png')img.save(full_path)# 更新内存中的数据if name not in self.webHref:self.webHref[name] = self.default_url# 更新表格row = self.table.rowCount()self.table.insertRow(row)self.table.setItem(row, 0, QTableWidgetItem(name))self.table.setItem(row, 1, QTableWidgetItem(self.default_url))# 检查img目录中是否存在对应的图片image_path = f'img/{name}.png'image_item = QTableWidgetItem("None" if not os.path.exists(image_path) else image_path)image_item.setFlags(image_item.flags() & ~Qt.ItemIsEditable) # 设置为只读self.table.setItem(row, 2, image_item)# 保存数据self.save_data()# 清空输入框self.icon_name_edit.clear()self.icon_text_edit.clear()QMessageBox.information(self, "成功", "图标生成成功!")except Exception as e:QMessageBox.critical(self, "错误", f"生成图标时出错:{str(e)}")def generate_md(self):"""生成Markdown文件"""try:self.status_label.setText("正在生成MD...")QApplication.processEvents()with open("software.md", "w", encoding="utf-8") as f:# 写入标题f.write(f"# 软件管理 {self.version}\n\n")f.write("> 本文档由软件管理器自动生成\n\n")# 写入目录f.write("## 目录\n\n")for root, _, _ in os.walk('.'):dirname = os.path.basename(root)if not dirname or dirname == '.' or dirname == 'img':continuef.write(f"- [{dirname}](#{dirname})\n")f.write("\n")# 写入软件列表for root, _, files in os.walk('.'):dirname = os.path.basename(root)if not dirname or dirname == '.' or dirname == 'img':continuef.write(f"## {dirname}\n\n")f.write("| 软件名 | 图标 | 外网链接 |\n")f.write("|--------|------|----------|\n")for file in files:base_name = self.get_string_before_dash(file)# 获取URL,确保是字符串而不是字典url_info = self.webHref.get(base_name, {})if isinstance(url_info, dict):official_url = url_info.get('url', self.default_url)else:official_url = self.default_url# 检查图片是否存在image_path = f'img/{base_name}.png'if os.path.exists(image_path):image_markdown = f""else:image_markdown = "无图标"f.write(f"| {file} | {image_markdown} | [外网]({official_url}) |\n")f.write("\n")self.status_label.setText("MD生成完成")QMessageBox.information(self, "成功", "Markdown文件生成成功!")except Exception as e:QMessageBox.critical(self, "错误", f"生成Markdown时出错:{str(e)}")self.status_label.setText("生成MD失败")def get_string_before_dash(self, s):"""获取字符串中破折号之前的内容"""dash_index = s.find('-')return s[:dash_index] if dash_index != -1 else sdef main():app = QApplication(sys.argv)window = SoftwareManager()window.show()sys.exit(app.exec())if __name__ == "__main__":main()
build.py
文件生成 exe用
import PyInstaller.__main__
import os# 确保当前工作目录正确
current_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(current_dir)PyInstaller.__main__.run(['software_manager.py','--name=software_manager','--windowed','--icon=app.ico', # 如果您有图标文件的话# '--version-file=version_info.txt','--clean','--noconfirm','--uac-admin', # 添加管理员权限'--onefile', # 打包成单一文件f'--workpath={os.path.join(current_dir, "build")}',f'--distpath={os.path.join(current_dir, "dist")}',f'--specpath={current_dir}'
])
index.css
主要样式文件
/* 基础公共样式:清除默认样式 + 设置通用样式*/
* {margin: 0;padding: 0;box-sizing: border-box;
}li {list-style: none;
}body {font: 14px/1.5 "Microsoft Yaher", "Hiragino Sans GB", "Heiti SC", "WenQuanYi Micro Hei", sans-serif;color: #333;
}a {color: #333;text-decoration: none;
}
/* 首页样式 */
/* 版心 */
.wrapper {margin: 0 auto;width: 100%;
}body {background-color: #f3f5f7;
} /* 精品推荐 */
.nav {position: fixed;top: 0;z-index: 999;display: flex;margin-top: 0px;padding: 0 20px;height: auto;min-height: 40px;border-radius: 5px;width: 100%;background-color: #FFF;box-shadow: 0px 1px 2px 0px rgba(211, 211, 211, 0.2);flex-wrap: wrap;align-items: center;
}
.nav h3 {font-size: 18px;color: brown;font-weight: 400;margin-right: 20px;white-space: nowrap;
}.nav ul {flex: 1;display: flex;flex-wrap: wrap;gap: 5px;
}.nav ul li {margin: 5px 0;
}.nav ul li a {padding: 0 8px;border-right: 1px solid #e0e0e0;font-size: 14px;padding: 5px 8px;border-radius: 3px;
}.nav li .active,
.nav li a:hover{border-bottom: 1px solid #00a4ff;
}.nav ul li:last-child a {border-right: 0;
}.nav ul li:nth-child(7) a {color: #217af7;
}
.nav ul li:nth-child(9) a {color: #fa6400;
}.nav .modify {font-size: 16px;color: #00a4ff;
}/* 推荐课程 */
.course {margin-top: 60px;
}/* 标题 公共类 与其他区域共用 */
.hd {display: flex;justify-content: space-between;height: 60px;line-height: 60px;
}.hd h3 {font-size: 21px;font-weight: 400;
}/* 课程内容 - 公共类 */
.bd ul {display: flex;flex-wrap: wrap;
}.bd li {position: relative;margin-bottom: 14px;margin-left: 10px;width: 228px;height: 251px; border-radius: 10px;overflow: hidden; border: 1px solid #ccc;background-color: #fff;display: flex;flex-direction: column;
}.bd .pic {width: 228px;height: 155px;overflow: hidden;
}.bd .pic img {width: 100%;height: 100%;object-fit: contain;
}.bd .text {padding: 10px;text-align: center;flex: 1;display: flex;flex-direction: column;justify-content: space-between;
}.bd li .text h3 {font-size: 14px;margin-bottom: 10px;/* 文字超出显示省略号 */overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}.bd li .text p {position: relative;margin-top: auto;height: 40px;display: flex;align-items: center;justify-content: center;
}.bd li .text p span {position: absolute;left: 10px;bottom: 5px;display: block;width: 60px;height: 30px;line-height: 30px;color: #fa6400;border: 1px solid #ccc;border-radius: 5px;
}.bd li .text p strong {position: absolute;right: 10px;bottom: 5px;display: block;width: 40px;height: 25px;line-height: 25px;background-color: #4E6EF2;color: #f7f6f5;border-radius: 5px;font-size: 12px;
}.bd li .text p i {position: absolute;top: -180px; /* 调整标签位置到图片上方 */left: 10px;font-style: normal;color: #FFF;font-size: 12px;background-color: #ffae00;height: 18px;line-height: 18px;padding: 0 5px;border-radius: 3px;z-index: 1;
}/* .bdx1 { *//* display: none; *//* 隐藏元素 元素会被完全移除,不再占据空间,也不可交互。*/
/* } */@media screen and (max-width: 1350px) {.nav {position: fixed;top: 0;z-index: 999;display: flex;flex-wrap: wrap;margin-top: 0px;padding: 10px 20px;min-height: 24px;height: auto;border-radius: 5px;box-shadow: 1px 1px 2px 1px rgba(30, 226, 12, 0.2);}.nav ul {flex: 1;display: flex;flex-wrap: wrap;gap: 5px;}.nav ul li a {background-color: rgba(90, 245, 51, 0.7);border-radius: 5px;font-weight: bold;display: block;padding: 5px 10px;white-space: nowrap;}}
software_urls.json
保存网址配置文件
{"AMD": {"url": "https://www.amd.com/zh-hans/support"},"AcroRdrDC": {"url": "https://get.adobe.com/cn/reader/"}
。。。。。。}
simsun.ttf 字体
目录里的文件名
取名要 AMD-yes 这样的格式 与“-”为分 前面 AMD 是主要数据名,图片名:AMD.png

index.html

software.md
相关文章:
Python 写生成 应用商店(2025版) 网页 方便收集应用 ,局域网使用
工具【1】:nginx 配置 nginx.conf 文件 server { listen 8080; server_name example.com; location / { root E:/BIT_Soft_2025; index index.html index.htm; } # 定义错误页面 error_page 404 /4…...
Spring 单元测试核心注解全解:@InjectMocks、@MockBean、@Mock、@Autowired 的区别与实战
在编写 Spring Boot 应用的单元测试过程中,@InjectMocks、@MockBean、@Mock 和 @Autowired 是最常用的几个注解,但它们经常被混淆或误用,导致测试失败或注入错误。 本文将从本质区别、使用场景、示例代码、对比表格等多个维度,全面解析这几者的使用方法与差异,助你写出结…...
2025年大一训练-DP1
2025年大一训练-DP1 Problem A: 动态规划算法,从上往下一层层找到到达对应位置的最大值,最底下一行maxl的最大值即为答案 #include<bits/stdc.h> using namespace std; int lst[101][101]; int maxl[101][101];int main() {int n,i,j;while(cin&g…...
【java 13天进阶Day04】常用API、正则表达式,泛型、Collection集合API
Math类的使用。 Math用于做数学运算。Math类中的方法全部是静态方法,直接用类名调用即可。方法: public static int abs(int a) 获取参数a的绝对值public static double ceil(double a) 向上取整public static double floor(double a) 向下取整public s…...
conversation_template | conversation_actors | conversation_line_template
目录 conversation_template conversation_actors conversation_line_template 实例应用 conversation_template id:某段谈话的唯一编号FirstLineId:谈话开始的第一段话的编号,取值来源 ConversationLine.db2 的 ID 字段TextureKitId&am…...
架构图--架构师的行军地图
架构图是架构师最重要的沟通和规划工具之一,它如同行军地图般指导着整个软件系统的构建与演进。本文系统性地探讨了软件架构图设计的全面方法论,提出横向与纵向双维度的设计框架。横向设计关注模块间的业务、数据与重要性关系,纵向设计则采用…...
`get_peft_model` 是 `peft` 库什么方法
get_peft_model 是 peft 库什么方法 get_peft_model 是 peft 库中一个关键的方法,其作用是将 LoRA 配置应用到预训练模型上,使得模型能够使用 LoRA 技术进行高效微调。 整体逻辑概述 get_peft_model 方法的核心任务是遍历预训练模型的各个模块,识别出需要应用 LoRA 的目标…...
OpenHarmony-Risc-V上运行openBLAS中的benchmark
OpenHarmony-Risc-V上运行openBLAS中的benchmark 文章目录 OpenHarmony-Risc-V上运行openBLAS中的benchmark前言一、编译openBLAS1.源码下载2.工具链下载3.编译并安装openBLAS 二、编译open BLAS中的benchmark三、上设备运行总结 前言 参考https://zhuanlan.zhihu.com/p/18825…...
HAL库通过FATFS和SDIO+DMA写入SD卡数据错误
HAL库F4版本 1.28.1 最近在使用HAL库配置SDIODMA并通过FATFS向SD卡写入数据,但是发现写入的数据经常有错误,不是少了一部分就是多了一部分,写入的数据为csv格式,通过循环向缓冲区写入"100100,12.345678\r\n"数据来观察问…...
深入解析 Python 中的装饰器 —— 从基础到实战
1. 装饰器基础 1.1 什么是装饰器? 装饰器本质上是一个 Python 函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能。装饰器的返回值也是一个函数对象。 1.2 语法糖: 符号 Python 提供了 符号作为装饰器的语法糖,…...
【Java并发】Java并发编程之CountDownLatch详解:原理、使用场景与代码实战
摘要 在Java多线程编程中,CountDownLatch 是一个强大的同步工具类,用于协调多个线程的执行顺序,线程间的同步是一个常见的需求。CountDownLatch 作为 java.util.concurrent 包中的一个同步辅助类,提供了一种简单而有效的方式来实…...
python-图片分割
图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,例如分割出物体、前景背景或特定的部分。在 Python 中,常用的图片分割方法包括传统的图像处理技术(例如阈值分割、区域生长等)和深度学习…...
江湖路远,唯PUT可稳:Express 路由更新招式全解
前言 江湖传闻,后端开发如同修炼绝世武功:有人精通 POST 掌,横扫千军;有人修习 GET 指法,探查万象。而真正踏入高阶境界的高手,常常默默修炼一门冷门却威力极强的秘技,PUT 神功。 今日时机正好,你我相逢于码海江湖,不如来一场技术切磋,也许能悟出更新之道,功力再上…...
MySQL:Join连接的原理
连接查询的执行过程: 确定第一个需要查询的表【驱动表】 选取代价最小的访问方法去执行单表查询语句 从驱动表每获取到一条记录,都需要到t2表中查找匹配的记录 两表连接查询需要查询一次t1表,两次t2表,在两表的连接查询中&…...
2025.04.14【Table】| 生信数据表图技巧
Custom title A set of examples showing how to customize the titles of a table made with GT Custom footer How to customize the footer and the references section of a gt table 文章目录 Custom titleCustom footer 生信数据可视化:Table图表详解1. R语…...
方案解读:虚拟电厂标杆项目整体建设方案【附全文阅读】
在电力市场背景下,传统电力现货市场存在电能定价不合理、分布式电源并网困难等问题。本虚拟电厂标杆项目旨在研究全时间尺度虚拟电厂智能管控关键技术,通过研制虚拟电厂控制器样机、开发运行管理平台,实现对分布式能源的合理优化配置。项目内容涵盖虚拟调控、建设目标、建设…...
使用Trae CN分析项目架构
架构分析后的截图 A区是打开的项目、B区是源码区、C区是AI给出当前项目的架构分析结果。 如何用 Trae CN 快速学习 STM32 嵌入式项目架构 在嵌入式开发领域,快速理解现有项目的架构是一项关键技能。Trae CN 作为一款强大的分析工具,能帮助开发者高效剖…...
【Python3】Django 学习之路
第一章:Django 简介 1.1 什么是 Django? Django 是一个高级的 Python Web 框架,旨在让 Web 开发变得更加快速和简便。它鼓励遵循“不要重复自己”(DRY,Don’t Repeat Yourself)的原则,并提供了…...
浏览器缩放后 element ui组件偏移
一、需求:当body的有了zoom值之后,element ui相关的popper弹框(下拉框、日期选择框、分页组件)位置都会出现偏移问题 二、问题来源 popper弹框都会需要根据屏幕x,y的坐标来设置位置,但是有了zoom值之后,x,y…...
FPGA学习——DE2-115开发板上设计波形发生器
1. 实验目的 掌握直接数字频率合成(DDS)技术的基本原理和应用。使用DE2-115开发板实现正弦波和方波的生成。使用SignalTap II嵌入式逻辑分析仪测试输出波形的离散数据。 2. 实验原理 DDS技术:通过相位累加器生成相位信息,结合波…...
Next.js 技术详解:构建现代化 Web 应用的全栈框架
1. Next.js 概述 Next.js 是一个基于 React 的全栈框架,由 Vercel 团队开发和维护。它提供了一系列开箱即用的功能,使开发者能够快速构建高性能的 Web 应用。 核心优势 服务端渲染 (SSR)静态站点生成 (SSG)增量静态再生成 (ISR)文件系统路由API 路由图…...
【springsecurity oauth2授权中心】简单案例跑通流程
项目被拆分开,需要一个授权中心使得每个项目都去授权中心登录获取用户权限。而单一项目里权限使用的是spring-security来控制的,每个controller方法上都有 PreAuthorize("hasAuthority(hello)") 注解来控制权限,想以最小的改动来实…...
golang channel源码
解析 数据结构 hchan:channel 数据结构 qcount:当前 channel 中存在多少个元素; dataqsize: 当前 channel 能存放的元素容量; buf:channel 中用于存放元素的环形缓冲区; elemsize:channel 元素…...
小刚说C语言刷题——1033 判断奇偶数
1.题目描述 输入一个整数,判断是否为偶数。是输出 y e s ,否则输出n o。 输入 输入只有一行,包括 1个整数(该整数在 1∼10000的范围内)。 输出 输出只有一行。(注意输出格式,具体请看下方提…...
2025TGCTF Web WP复现
AAA 偷渡阴平 <?php$tgctf2025$_GET[tgctf2025];if(!preg_match("/0|1|[3-9]|\~|\|\|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\|\|\{|\[|\]|\}|\:|\|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $tgctf2025)){//hint:你可以对着键盘…...
基于DeepSeek的考研暑假日志分析
注:我去年考研时写了日志,大致记录了我每天的主要活动。由于过于琐碎,一直没有翻看。突发奇想,现在利用deepseek总结其中规律。 从你的日志中可以总结出以下规律和活动兴衰起落: 一、学习活动规律与演变 …...
「GitHub热榜」AIGC系统源码:AI问答+绘画+PPT+音乐生成一站式
—零门槛搭建私有化AI内容工厂,源码开放商业落地指南 为什么全栈AIGC系统成为企业刚需? 1. 传统方案的致命缺陷 痛点 使用ChatGPTMidjourneyCanva 本全栈方案 工具割裂 需切换5平台 一个系统全搞定 成本 年费50万 一次部署永久免费 数据安全 …...
AWS上构建基于自然语言的数值和符号计算系统
我想要实现一个通过使用C#、Semantic Kernel库、OpenAI GPT 4的API和以下使用C#开源库MathNet实现通过中文自然语言提示词中包含LATEX代码输入到系统,通过以下符号和数值计算和其它符号和数值计算程序输出计算结果和必要步骤的应用,这样的数学计算使用程序直接产生结果,可以…...
【C++】 —— 笔试刷题day_19
一、小易的升级之路 题目解析 小易现在要打游戏,现在游戏角色的初始能力值为a,我们会遇到n个怪,这些怪物的防御值为b1、b2、b3...,如果我们的能力值要高于或者等于怪物的防御值,那我们的能力值就会加bi;如…...
解决 Spring Boot 多数据源环境下事务管理器冲突问题(非Neo4j请求标记了 @Transactional 尝试启动Neo4j的事务管理器)
0. 写在前面 到底遇到了什么问题? 简洁版: 在 Oracle 与 Neo4j 共存的多数据源项目中,一个仅涉及 Oracle 操作的请求,却因为 Neo4j 连接失败而报错。根本原因是 Spring 的默认事务管理器错误地指向了 Neo4j,导致不相…...
