diff --git a/sql/update_20260224_spider_news.sql b/sql/update_20260224_spider_news.sql
index 1a43a3e..fa1f68f 100644
--- a/sql/update_20260224_spider_news.sql
+++ b/sql/update_20260224_spider_news.sql
@@ -2,6 +2,7 @@
CREATE TABLE IF NOT EXISTS `pap_spider_news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`origin_id` int(11) NOT NULL DEFAULT 0 COMMENT '原站文章ID',
+ `type` varchar(20) NOT NULL DEFAULT 'news' COMMENT '来源类型 news/about',
`title` varchar(500) NOT NULL DEFAULT '' COMMENT '文章标题',
`category` varchar(100) DEFAULT '' COMMENT '原站栏目分类',
`publish_time` datetime DEFAULT NULL COMMENT '原站发布时间',
@@ -16,6 +17,6 @@ CREATE TABLE IF NOT EXISTS `pap_spider_news` (
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
- UNIQUE KEY `uk_origin_id` (`origin_id`),
+ UNIQUE KEY `uk_type_origin_id` (`type`, `origin_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='爬虫-新闻数据';
diff --git a/sql/update_20260225_spider_to_article.sql b/sql/update_20260225_spider_to_article.sql
new file mode 100644
index 0000000..ba80900
--- /dev/null
+++ b/sql/update_20260225_spider_to_article.sql
@@ -0,0 +1,23 @@
+-- 将 pap_spider_news 中 id=119~126 的公益项目数据转入 pap_article,column_id=5
+-- content 优先取已转存的 content,其次取原始 content_original
+INSERT INTO `pap_article` (`column_id`, `title`, `summary`, `content`, `cover`, `category`, `is_top`, `status`, `publish_time`, `sort`, `create_time`)
+SELECT
+ 5 AS column_id,
+ s.title,
+ '' AS summary,
+ COALESCE(s.content, s.content_original, '') AS content,
+ COALESCE(s.cover, s.cover_original, '') AS cover,
+ s.category,
+ 0 AS is_top,
+ 1 AS status,
+ s.publish_time,
+ 0 AS sort,
+ NOW()
+FROM `pap_spider_news` s
+WHERE s.id IN (119, 120, 121, 122, 123, 124, 125, 126);
+
+-- 回写 article_id 到 spider_news(方便追溯)
+UPDATE `pap_spider_news` sn
+INNER JOIN `pap_article` a ON a.title = sn.title AND a.column_id = 5
+SET sn.article_id = a.id, sn.status = 3
+WHERE sn.id IN (119, 120, 121, 122, 123, 124, 125, 126);
diff --git a/sql/update_20260225_spider_type.sql b/sql/update_20260225_spider_type.sql
new file mode 100644
index 0000000..b41fad5
--- /dev/null
+++ b/sql/update_20260225_spider_type.sql
@@ -0,0 +1,4 @@
+-- 给spider_news表添加type字段,区分news和about
+ALTER TABLE `pap_spider_news` ADD COLUMN `type` varchar(20) NOT NULL DEFAULT 'news' COMMENT '来源类型 news/about' AFTER `origin_id`;
+ALTER TABLE `pap_spider_news` DROP INDEX `uk_origin_id`;
+ALTER TABLE `pap_spider_news` ADD UNIQUE KEY `uk_type_origin_id` (`type`, `origin_id`);
diff --git a/sql/update_20260227_column_extend.sql b/sql/update_20260227_column_extend.sql
new file mode 100644
index 0000000..3d8760b
--- /dev/null
+++ b/sql/update_20260227_column_extend.sql
@@ -0,0 +1,12 @@
+-- 栏目表扩展:增加前台展示字段
+ALTER TABLE `pap_column` ADD COLUMN `name_en` varchar(200) DEFAULT '' COMMENT '英文名称' AFTER `name`;
+ALTER TABLE `pap_column` ADD COLUMN `description` varchar(500) DEFAULT '' COMMENT '栏目描述/副标题' AFTER `name_en`;
+ALTER TABLE `pap_column` ADD COLUMN `banner_image` varchar(500) DEFAULT '' COMMENT '栏目Banner背景图' AFTER `description`;
+
+-- 更新现有一级栏目数据
+UPDATE `pap_column` SET name_en = 'ABOUT US', description = '苍穹 笃行 创新 守止' WHERE `key` = 'about';
+UPDATE `pap_column` SET name_en = 'PUBLIC WELFARE PROJECTS', description = '聚焦健康公益,守护每一份希望' WHERE `key` = 'project';
+UPDATE `pap_column` SET name_en = 'PARTY BUILDING', description = '不忘初心 牢记使命' WHERE `key` = 'party';
+UPDATE `pap_column` SET name_en = 'INFORMATION DISCLOSURE', description = '公开透明 接受监督' WHERE `key` = 'disclosure';
+UPDATE `pap_column` SET name_en = 'NEWS CENTER', description = '了解基金会最新动态' WHERE `key` = 'news';
+UPDATE `pap_column` SET name_en = 'CONTACT US', description = '期待与您携手同行' WHERE `key` = 'contact';
diff --git a/src/config/adapter.js b/src/config/adapter.js
index 7ddfafd..95fe283 100644
--- a/src/config/adapter.js
+++ b/src/config/adapter.js
@@ -44,7 +44,8 @@ exports.model = {
port: '26821',
user: 'root',
password: '5orKUdDN3QhESVcS',
- dateStrings: true
+ dateStrings: true,
+ connectionLimit: 10
}
};
diff --git a/src/config/router.js b/src/config/router.js
index 6c28447..30bd2b0 100644
--- a/src/config/router.js
+++ b/src/config/router.js
@@ -3,6 +3,10 @@ module.exports = [
['/', 'index/index'],
['/index', 'index/index'],
+ // 一级栏目页面(带子栏目)
+ ['/column/:key', 'column/index', 'get'],
+ ['/column/:key/:child', 'column/index', 'get'],
+
// 后台管理路由
['/admin/login', 'admin/auth/login', 'get'],
['/admin/auth/login', 'admin/auth/doLogin', 'post'],
@@ -110,6 +114,7 @@ module.exports = [
// 爬虫工具
['/admin/spider/fetch-list', 'admin/spider/fetchList'],
+ ['/admin/spider/fetch-about-list', 'admin/spider/fetchAboutList'],
['/admin/spider/fetch-detail', 'admin/spider/fetchDetail'],
['/admin/spider/transfer-images', 'admin/spider/transferImages'],
['/admin/spider/sync', 'admin/spider/sync'],
diff --git a/src/controller/admin/dashboard.js b/src/controller/admin/dashboard.js
index 18d44d1..123c235 100644
--- a/src/controller/admin/dashboard.js
+++ b/src/controller/admin/dashboard.js
@@ -20,18 +20,9 @@ module.exports = class extends Base {
// 待办事项(后续从数据库获取)
this.assign('todoList', []);
- // 动态栏目菜单(后续从接口获取)
- this.assign('columnMenus', await this.getColumnMenus());
-
// 当前登录用户
this.assign('adminUser', this.adminUser || {});
return this.display();
}
-
- // 获取动态栏目菜单(暂时返回空,后续从数据库获取)
- async getColumnMenus() {
- // TODO: 从数据库获取栏目配置
- return [];
- }
};
diff --git a/src/controller/admin/spider.js b/src/controller/admin/spider.js
index b1426b9..ac47768 100644
--- a/src/controller/admin/spider.js
+++ b/src/controller/admin/spider.js
@@ -26,7 +26,7 @@ module.exports = class extends Base {
async fetchListAction() {
try {
const res = await axios.post(
- `${ORIGIN.listUrl}?act=contentlist&id=&type=news`,
+ `${ORIGIN.listUrl}?act=contentlist&id=&type=product`,
'order=asc&limit=9999&offset=0',
{
headers: {
@@ -53,7 +53,7 @@ module.exports = class extends Base {
const publishTime = this.extractTime(row.c_addtime);
// 检查是否已存在
- const exists = await model.where({ origin_id: originId }).find();
+ const exists = await model.where({ origin_id: originId, type: 'news' }).find();
if (exists && exists.id) {
skipped++;
continue;
@@ -64,6 +64,7 @@ module.exports = class extends Base {
title,
category,
publish_time: publishTime,
+ type: 'product',
status: 0
});
inserted++;
@@ -80,6 +81,67 @@ module.exports = class extends Base {
}
}
+ /**
+ * 步骤1b:拉取about列表并入库
+ * GET /admin/spider/fetch-about-list
+ * 参数: sid (可选,指定栏目sid)
+ */
+ async fetchAboutListAction() {
+ try {
+ const sid = this.get('sid') || '';
+ const res = await axios.post(
+ `${ORIGIN.listUrl}?act=aboutlist&sid=${sid}`,
+ 'order=asc&limit=9999&offset=0',
+ {
+ headers: {
+ Cookie: ORIGIN.cookie,
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ }
+ }
+ );
+
+ const rows = res.data;
+ if (!rows || !Array.isArray(rows)) {
+ return this.json({ code: 1, msg: 'about列表数据获取失败' });
+ }
+
+ const model = this.model('spider_news');
+ let inserted = 0;
+ let skipped = 0;
+
+ for (const row of rows) {
+ const originId = parseInt(row.id);
+ const title = this.extractTitle(row.a_name);
+ const category = row.sid || '';
+
+ // 检查是否已存在
+ const exists = await model.where({ origin_id: originId, type: 'about' }).find();
+ if (exists && exists.id) {
+ skipped++;
+ continue;
+ }
+
+ await model.add({
+ origin_id: originId,
+ title,
+ category,
+ type: 'about',
+ status: 0
+ });
+ inserted++;
+ }
+
+ return this.json({
+ code: 0,
+ msg: `about列表拉取完成,新增${inserted}条,跳过${skipped}条`,
+ data: { total: rows.length, inserted, skipped }
+ });
+ } catch (err) {
+ think.logger.error('拉取about列表失败:', err);
+ return this.json({ code: 1, msg: '拉取about列表失败: ' + err.message });
+ }
+ }
+
/**
* 步骤2:爬取详情页内容
* GET /admin/spider/fetch-detail
@@ -87,14 +149,19 @@ module.exports = class extends Base {
*/
async fetchDetailAction() {
const targetId = this.get('id');
+ const type = this.get('type') || '';
const model = this.model('spider_news');
- let list;
+ let where = { status: 0 };
if (targetId) {
- list = await model.where({ origin_id: targetId }).select();
- } else {
- list = await model.where({ status: 0 }).select();
+ where = { origin_id: targetId };
+ if (type) where.type = type;
}
+ if (type && !targetId) {
+ where.type = type;
+ }
+
+ const list = await model.where(where).select();
if (!list.length) {
return this.json({ code: 0, msg: '没有待爬取的记录' });
@@ -105,7 +172,7 @@ module.exports = class extends Base {
for (const item of list) {
try {
- const detailUrl = `${ORIGIN.base}/?news/${item.origin_id}.html`;
+ const detailUrl = `${ORIGIN.base}/?${type}/${item.origin_id}.html`
const res = await axios.get(detailUrl, {
headers: { Cookie: ORIGIN.cookie },
responseType: 'arraybuffer'
@@ -168,15 +235,20 @@ module.exports = class extends Base {
*/
async transferImagesAction() {
const targetId = this.get('id');
+ const type = this.get('type') || '';
const model = this.model('spider_news');
- let list;
+ let where = { status: 1 };
if (targetId) {
- list = await model.where({ origin_id: targetId }).select();
- } else {
- list = await model.where({ status: 1 }).select();
+ where = { origin_id: targetId };
+ if (type) where.type = type;
+ }
+ if (type && !targetId) {
+ where.type = type;
}
+ const list = await model.where(where).select();
+
if (!list.length) {
return this.json({ code: 0, msg: '没有待转存图片的记录' });
}
diff --git a/src/controller/admin/system/column.js b/src/controller/admin/system/column.js
index f20da62..124ec01 100644
--- a/src/controller/admin/system/column.js
+++ b/src/controller/admin/system/column.js
@@ -54,6 +54,9 @@ module.exports = class extends Base {
const id = await model.add({
parent_id: data.parent_id || 0,
name: data.name,
+ name_en: data.name_en || '',
+ description: data.description || '',
+ banner_image: data.banner_image || '',
key: data.key || '',
icon: data.icon || '',
type: data.type || '',
@@ -88,6 +91,9 @@ module.exports = class extends Base {
await this.model('column').where({ id }).update({
parent_id: data.parent_id || 0,
name: data.name,
+ name_en: data.name_en || '',
+ description: data.description || '',
+ banner_image: data.banner_image || '',
key: data.key || '',
icon: data.icon || '',
type: data.type || '',
diff --git a/src/controller/base.js b/src/controller/base.js
index 7a2d9ef..9254aff 100644
--- a/src/controller/base.js
+++ b/src/controller/base.js
@@ -12,6 +12,7 @@ const WHITE_LIST = [
'/admin/logout',
// 爬虫工具
'/admin/spider/fetch-list',
+ '/admin/spider/fetch-about-list',
'/admin/spider/fetch-detail',
'/admin/spider/transfer-images',
'/admin/spider/sync',
@@ -49,8 +50,9 @@ module.exports = class extends think.Controller {
}
}
- // 白名单放行
- if (WHITE_LIST.includes(path)) {
+ // 白名单放行(同时匹配带.html后缀的路径)
+ const pathNoSuffix = path.replace(/\.html$/, '');
+ if (WHITE_LIST.includes(path) || WHITE_LIST.includes(pathNoSuffix)) {
return;
}
diff --git a/src/controller/column.js b/src/controller/column.js
new file mode 100644
index 0000000..5110194
--- /dev/null
+++ b/src/controller/column.js
@@ -0,0 +1,112 @@
+const Base = require('./base.js');
+
+module.exports = class extends Base {
+ async indexAction() {
+ const columnKey = this.get('key');
+ const childKey = this.get('child');
+
+ if (!columnKey) return this.redirect('/');
+
+ // 获取所有栏目
+ const columns = await this.model('column').where({ is_deleted: 0, visible: 1 }).order('sort ASC').select();
+ const navMenus = this.buildNavTree(columns);
+
+ // 找到当前一级栏目
+ const column = columns.find(c => c.key === columnKey && c.parent_id === 0);
+ if (!column) return this.redirect('/');
+
+ // 获取子栏目
+ const children = columns.filter(c => c.parent_id === column.id).sort((a, b) => a.sort - b.sort);
+
+ // 确定当前选中的子栏目
+ let currentChild = null;
+ if (childKey) {
+ currentChild = children.find(c => c.key === childKey);
+ }
+ if (!currentChild && children.length > 0) {
+ currentChild = children[0];
+ }
+
+ // 根据子栏目类型加载内容
+ let contentData = {};
+ if (currentChild) {
+ contentData = await this.loadContent(currentChild);
+ }
+
+ // 网站配置
+ const configList = await this.model('config').select();
+ const siteConfig = {};
+ configList.forEach(c => { siteConfig[c.key] = c.value; });
+
+ this.assign({
+ navMenus,
+ column,
+ children,
+ currentChild,
+ contentData,
+ siteConfig,
+ currentColumnKey: columnKey
+ });
+
+ return this.display('column_index');
+ }
+
+ // 根据类型加载内容
+ async loadContent(child) {
+ const colId = child.id;
+ const type = child.type;
+
+ switch (type) {
+ case 'page': {
+ const page = await this.model('page').where({ column_id: colId, is_deleted: 0 }).find();
+ return { type: 'page', page: page || {} };
+ }
+ case 'article': {
+ const list = await this.model('article').where({ column_id: colId, status: 1, is_deleted: 0 })
+ .order('is_top DESC, sort DESC, publish_time DESC').limit(20).select();
+ // 格式化日期
+ list.forEach(item => {
+ if (item.publish_time) {
+ const d = new Date(item.publish_time);
+ item.publish_date = d.getFullYear() + '.' + String(d.getMonth() + 1).padStart(2, '0') + '.' + String(d.getDate()).padStart(2, '0');
+ }
+ });
+ return { type: 'article', list };
+ }
+ case 'image': {
+ const list = await this.model('image').where({ column_id: colId, status: 1, is_deleted: 0 })
+ .order('sort ASC').select();
+ return { type: 'image', list };
+ }
+ case 'text': {
+ const list = await this.model('text').where({ column_id: colId, status: 1, is_deleted: 0 })
+ .order('sort ASC, id DESC').select();
+ return { type: 'text', list };
+ }
+ case 'person': {
+ const list = await this.model('person').where({ column_id: colId, status: 1, is_deleted: 0 })
+ .order('sort ASC').select();
+ return { type: 'person', list };
+ }
+ case 'job': {
+ const list = await this.model('job').where({ column_id: colId, status: 1, is_deleted: 0 })
+ .order('sort ASC, id DESC').select();
+ return { type: 'job', list };
+ }
+ default:
+ return { type: type || 'empty' };
+ }
+ }
+
+ // 构建导航树
+ buildNavTree(columns) {
+ const tree = [];
+ const map = {};
+ columns.forEach(item => { map[item.id] = { ...item, children: [] }; });
+ columns.forEach(item => {
+ if (item.parent_id === 0) tree.push(map[item.id]);
+ else if (map[item.parent_id]) map[item.parent_id].children.push(map[item.id]);
+ });
+ return tree;
+ }
+};
diff --git a/src/controller/index.js b/src/controller/index.js
index 6447f83..3cf57cb 100644
--- a/src/controller/index.js
+++ b/src/controller/index.js
@@ -1,10 +1,26 @@
const Base = require('./base.js');
+// 首页数据内存缓存
+let homeCache = null;
+let homeCacheTime = 0;
+const CACHE_TTL = 60 * 1000; // 60秒缓存
+
module.exports = class extends Base {
async indexAction() {
+ const t0 = Date.now();
+
+ // 检查缓存
+ if (homeCache && (Date.now() - homeCacheTime < CACHE_TTL)) {
+ console.log(`[perf] cache hit, age: ${Date.now() - homeCacheTime}ms`);
+ this.assign(homeCache);
+ return this.display();
+ }
+
// 获取栏目配置
const columns = await this.model('column').where({ is_deleted: 0, visible: 1 }).order('sort ASC').select();
-
+ const t1 = Date.now();
+ console.log(`[perf] columns: ${t1 - t0}ms`);
+
// 构建导航菜单树
const navMenus = this.buildNavTree(columns);
@@ -14,71 +30,76 @@ module.exports = class extends Base {
const colMap = {};
homeChildren.forEach(c => { colMap[c.key] = c.id; });
- // 获取Banner数据(根据栏目key查找column_id,或者column_id=0表示通用)
const bannerColId = colMap['home-banner'] || 0;
- const banners = await this.model('banner').where({
- status: 1,
- is_deleted: 0
- }).where('column_id = ' + bannerColId + ' OR column_id = 0').order('sort ASC').select();
-
- // 获取捐赠统计
const dataColId = colMap['home-data'] || 0;
- let donationStat = await this.model('donation_stat').where({
- column_id: dataColId
- }).find();
+ const projectColId = colMap['home-project'] || 0;
+ const newsColId = colMap['home-news'] || 0;
+ const partnerColId = colMap['home-partner'] || 0;
+
+ const t2 = Date.now();
+ // 并行查询所有数据
+ const [
+ banners,
+ donationStatResult,
+ donationIncome,
+ donationExpense,
+ medicines,
+ projects,
+ newsList,
+ partners,
+ configList
+ ] = await Promise.all([
+ this.model('banner').where({ status: 1, is_deleted: 0 })
+ .where('column_id = ' + bannerColId + ' OR column_id = 0').order('sort ASC').select(),
+ this.model('donation_stat').where({ column_id: dataColId }).find(),
+ this.model('donation').where({ type: 'income', status: 1, is_deleted: 0 })
+ .where('column_id = ' + dataColId + ' OR column_id = 0').order('record_date DESC').limit(10).select(),
+ this.model('donation').where({ type: 'expense', status: 1, is_deleted: 0 })
+ .where('column_id = ' + dataColId + ' OR column_id = 0').order('record_date DESC').limit(10).select(),
+ this.model('medicine').where({ status: 1, is_deleted: 0 })
+ .order('distribute_date DESC').limit(20).select(),
+ this.model('article').where({ status: 1, is_deleted: 0 })
+ .where('column_id = ' + projectColId + ' OR column_id = 0').order('sort DESC, publish_time DESC').limit(5).select(),
+ this.model('article').where({ status: 1, is_deleted: 0 })
+ .where('column_id = ' + newsColId + ' OR column_id = 0').order('is_top DESC, publish_time DESC').limit(5).select(),
+ this.model('image').where({ status: 1, is_deleted: 0 })
+ .where('column_id = ' + partnerColId + ' OR column_id = 0').order('sort ASC').select(),
+ this.model('config').select()
+ ]);
+ const t3 = Date.now();
+ console.log(`[perf] parallel queries: ${t3 - t2}ms`);
+
+ // 捐赠统计兜底
+ let donationStat = donationStatResult;
if (!donationStat || !donationStat.id) {
donationStat = await this.model('donation_stat').where({ column_id: 0 }).find();
}
donationStat = donationStat || { total_income: 0, total_expense: 0, year_income: 0 };
-
- // 获取捐赠明细(收入/支出各取最新10条)
- const donationIncome = await this.model('donation').where({
- type: 'income',
- status: 1,
- is_deleted: 0
- }).where('column_id = ' + dataColId + ' OR column_id = 0').order('record_date DESC').limit(10).select();
-
- const donationExpense = await this.model('donation').where({
- type: 'expense',
- status: 1,
- is_deleted: 0
- }).where('column_id = ' + dataColId + ' OR column_id = 0').order('record_date DESC').limit(10).select();
-
- // 获取药品援助数据(只显示已发放的)
- const medicines = await this.model('medicine').where({
- status: 1,
- is_deleted: 0
- }).order('distribute_date DESC').limit(20).select();
-
- // 获取公益项目
- const projectColId = colMap['home-project'] || 0;
- const projects = await this.model('article').where({
- status: 1,
- is_deleted: 0
- }).where('column_id = ' + projectColId + ' OR column_id = 0').order('sort DESC, publish_time DESC').limit(5).select();
-
- // 获取新闻动态
- const newsColId = colMap['home-news'] || 0;
- const newsList = await this.model('article').where({
- status: 1,
- is_deleted: 0
- }).where('column_id = ' + newsColId + ' OR column_id = 0').order('is_top DESC, publish_time DESC').limit(5).select();
-
- // 获取合作伙伴
- const partnerColId = colMap['home-partner'] || 0;
- const partners = await this.model('image').where({
- status: 1,
- is_deleted: 0
- }).where('column_id = ' + partnerColId + ' OR column_id = 0').order('sort ASC').select();
-
- // 获取网站配置
- const configList = await this.model('config').select();
+
+ // 格式化日期
+ const formatDate = (str) => {
+ if (!str) return { date: '', day: '', ym: '' };
+ const d = new Date(str);
+ if (isNaN(d.getTime())) return { date: '', day: '', ym: '' };
+ const y = d.getFullYear();
+ const m = String(d.getMonth() + 1).padStart(2, '0');
+ const dd = String(d.getDate()).padStart(2, '0');
+ return { date: y + '.' + m + '.' + dd, day: dd, ym: y + '.' + m };
+ };
+ newsList.forEach(item => {
+ const fd = formatDate(item.publish_time);
+ item.publish_date = fd.date;
+ item.publish_day = fd.day;
+ item.publish_ym = fd.ym;
+ });
+
+ // 网站配置
const siteConfig = {};
configList.forEach(c => {
siteConfig[c.key] = c.value;
});
- this.assign({
+ const data = {
navMenus,
banners,
donationStat,
@@ -90,8 +111,16 @@ module.exports = class extends Base {
partners,
siteConfig,
now: new Date()
- });
+ };
+
+ // 写入缓存
+ homeCache = data;
+ homeCacheTime = Date.now();
+
+ this.assign(data);
+ const t4 = Date.now();
+ console.log(`[perf] TOTAL: ${t4 - t0}ms`);
return this.display();
}
diff --git a/view/admin/auth_login.html b/view/admin/auth_login.html
index e7f2d6b..a048824 100644
--- a/view/admin/auth_login.html
+++ b/view/admin/auth_login.html
@@ -199,10 +199,10 @@ document.getElementById('loginForm').addEventListener('submit', async function(e
body: JSON.stringify({ username, password, remember })
});
const data = await res.json();
- if (data.errno === 0) {
+ if (data.code === 0) {
window.location.href = '/admin/dashboard.html';
} else {
- errorMsg.textContent = data.errmsg || '登录失败';
+ errorMsg.textContent = data.msg || '登录失败';
errorMsg.classList.add('show');
}
} catch (err) {
diff --git a/view/admin/system/column_index.html b/view/admin/system/column_index.html
index 62b6adc..1a74890 100644
--- a/view/admin/system/column_index.html
+++ b/view/admin/system/column_index.html
@@ -46,6 +46,19 @@
{{item.summary}}
+ {% endif %} + +{{item.description}}
{% endif %} +