Compare commits
No commits in common. "2dbf1a859e85dd4fc9f9d24fb78c00c8ad6aa8a6" and "1de17afa1c800cbee8508d3e1458ddc1cbaea456" have entirely different histories.
2dbf1a859e
...
1de17afa1c
@ -1,30 +1,3 @@
|
|||||||
CREATE TABLE `enterprise_news_article` (
|
|
||||||
`id` varchar(32) NOT NULL COMMENT '唯一标识符',
|
|
||||||
`domain_name` varchar(64) NOT NULL COMMENT '所属域名',
|
|
||||||
`title_zh` varchar(100) DEFAULT NULL COMMENT '中文标题',
|
|
||||||
`title_en` varchar(100) DEFAULT NULL COMMENT '英文标题',
|
|
||||||
`summary_zh` varchar(255) DEFAULT NULL COMMENT '中文摘要',
|
|
||||||
`summary_en` varchar(255) DEFAULT NULL COMMENT '英文摘要',
|
|
||||||
`article_type_zh` varchar(20) DEFAULT NULL COMMENT '中文文章类型',
|
|
||||||
`article_type_en` varchar(20) DEFAULT NULL COMMENT '英文文章类型',
|
|
||||||
`content_zh` text DEFAULT NULL COMMENT '中文正文',
|
|
||||||
`content_en` text DEFAULT NULL COMMENT '英文正文',
|
|
||||||
`title` varchar(100) DEFAULT NULL COMMENT '文章标题',
|
|
||||||
`article_type` varchar(20) DEFAULT NULL COMMENT '文章类型(企业动态/产品动态/行业洞察/活动资讯)',
|
|
||||||
`summary` varchar(255) DEFAULT NULL COMMENT '文章摘要',
|
|
||||||
`cover_img` varchar(255) DEFAULT NULL COMMENT '封面图片',
|
|
||||||
`content` text DEFAULT NULL COMMENT '文章正文',
|
|
||||||
`status` varchar(1) DEFAULT '0' COMMENT '状态(0-草稿/1-已发布)',
|
|
||||||
`publish_time` date DEFAULT NULL COMMENT '发布时间',
|
|
||||||
`read_count` int(11) DEFAULT 0 COMMENT '阅读数据',
|
|
||||||
`del_flg` varchar(1) DEFAULT '0' COMMENT '删除标志(0-正常/1-已删除)',
|
|
||||||
`update_time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '更新时间',
|
|
||||||
`create_at` timestamp NULL DEFAULT current_timestamp() COMMENT '创建时间',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='企业文章表';
|
|
||||||
|
|
||||||
|
|
||||||
# 旧版本表结构
|
|
||||||
CREATE TABLE `enterprise_news_article` (
|
CREATE TABLE `enterprise_news_article` (
|
||||||
`id` varchar(32) NOT NULL COMMENT '唯一标识符',
|
`id` varchar(32) NOT NULL COMMENT '唯一标识符',
|
||||||
`domain_name` varchar(64) NOT NULL COMMENT '所属域名',
|
`domain_name` varchar(64) NOT NULL COMMENT '所属域名',
|
||||||
|
|||||||
@ -11,9 +11,7 @@ async def front_news_detail(ns={}):
|
|||||||
update_sql = """update enterprise_news_article set read_count = ifnull(read_count, 0) + 1 where id = '%s' and status = '1' and del_flg = '0';""" % ns.get('id')
|
update_sql = """update enterprise_news_article set read_count = ifnull(read_count, 0) + 1 where id = '%s' and status = '1' and del_flg = '0';""" % ns.get('id')
|
||||||
await sor.sqlExe(update_sql, {})
|
await sor.sqlExe(update_sql, {})
|
||||||
search_sql = """
|
search_sql = """
|
||||||
select id, title_zh, title_en, article_type_zh, article_type_en,
|
select id, title, article_type, summary, cover_img, content, publish_time, read_count
|
||||||
summary_zh, summary_en, cover_img, content_zh, content_en,
|
|
||||||
publish_time, read_count
|
|
||||||
from enterprise_news_article
|
from enterprise_news_article
|
||||||
where id = '%s' and status = '1' and del_flg = '0';
|
where id = '%s' and status = '1' and del_flg = '0';
|
||||||
""" % ns.get('id')
|
""" % ns.get('id')
|
||||||
|
|||||||
@ -13,14 +13,10 @@ async def front_news_search(ns={}):
|
|||||||
offset = (current_page - 1) * page_size
|
offset = (current_page - 1) * page_size
|
||||||
|
|
||||||
conditions = ["domain_name = '%s'" % domain_name, "status = '1'", "del_flg = '0'"]
|
conditions = ["domain_name = '%s'" % domain_name, "status = '1'", "del_flg = '0'"]
|
||||||
if ns.get('article_type_zh'):
|
if ns.get('article_type'):
|
||||||
conditions.append("article_type_zh = '%s'" % ns.get('article_type_zh'))
|
conditions.append("article_type = '%s'" % ns.get('article_type'))
|
||||||
if ns.get('article_type_en'):
|
if ns.get('title'):
|
||||||
conditions.append("article_type_en = '%s'" % ns.get('article_type_en'))
|
conditions.append("title like '%%%%%s%%%%'" % ns.get('title'))
|
||||||
if ns.get('title_zh'):
|
|
||||||
conditions.append("title_zh like '%%%%%s%%%%'" % ns.get('title_zh'))
|
|
||||||
if ns.get('title_en'):
|
|
||||||
conditions.append("title_en like '%%%%%s%%%%'" % ns.get('title_en'))
|
|
||||||
where_clause = " and ".join(conditions)
|
where_clause = " and ".join(conditions)
|
||||||
|
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
@ -29,8 +25,7 @@ async def front_news_search(ns={}):
|
|||||||
count_sql = """select count(*) as total_count from enterprise_news_article where %s;""" % where_clause
|
count_sql = """select count(*) as total_count from enterprise_news_article where %s;""" % where_clause
|
||||||
total_count = (await sor.sqlExe(count_sql, {}))[0]['total_count']
|
total_count = (await sor.sqlExe(count_sql, {}))[0]['total_count']
|
||||||
search_sql = """
|
search_sql = """
|
||||||
select id, title_zh, title_en, article_type_zh, article_type_en,
|
select id, title, article_type, summary, cover_img, publish_time, read_count
|
||||||
summary_zh, summary_en, cover_img, publish_time, read_count
|
|
||||||
from enterprise_news_article
|
from enterprise_news_article
|
||||||
where %s
|
where %s
|
||||||
order by publish_time desc, update_time desc
|
order by publish_time desc, update_time desc
|
||||||
|
|||||||
@ -4,11 +4,16 @@ async def news_article_add(ns={}):
|
|||||||
'status': False,
|
'status': False,
|
||||||
'msg': '请传递url_link'
|
'msg': '请传递url_link'
|
||||||
}
|
}
|
||||||
if not ns.get('title_zh'):
|
if not ns.get('title'):
|
||||||
return {
|
return {
|
||||||
'status': False,
|
'status': False,
|
||||||
'msg': '请传递中文标题'
|
'msg': '请传递标题'
|
||||||
}
|
}
|
||||||
|
# if ns.get('article_type') not in ['企业动态', '产品动态', '行业洞察', '活动资讯']:
|
||||||
|
# return {
|
||||||
|
# 'status': False,
|
||||||
|
# 'msg': '文章类型错误'
|
||||||
|
# }
|
||||||
|
|
||||||
domain_name = ns.get('url_link').split("//")[1].split("/")[0]
|
domain_name = ns.get('url_link').split("//")[1].split("/")[0]
|
||||||
if 'localhost' in domain_name:
|
if 'localhost' in domain_name:
|
||||||
@ -21,15 +26,11 @@ async def news_article_add(ns={}):
|
|||||||
ns_dic = {
|
ns_dic = {
|
||||||
'id': uuid(),
|
'id': uuid(),
|
||||||
'domain_name': domain_name,
|
'domain_name': domain_name,
|
||||||
'title_zh': ns.get('title_zh'),
|
'title': ns.get('title'),
|
||||||
'title_en': ns.get('title_en'),
|
'article_type': ns.get('article_type'),
|
||||||
'article_type_zh': ns.get('article_type_zh'),
|
'summary': ns.get('summary'),
|
||||||
'article_type_en': ns.get('article_type_en'),
|
|
||||||
'summary_zh': ns.get('summary_zh'),
|
|
||||||
'summary_en': ns.get('summary_en'),
|
|
||||||
'cover_img': ns.get('cover_img'),
|
'cover_img': ns.get('cover_img'),
|
||||||
'content_zh': ns.get('content_zh'),
|
'content': ns.get('content'),
|
||||||
'content_en': ns.get('content_en'),
|
|
||||||
'status': status,
|
'status': status,
|
||||||
'publish_time': ns.get('publish_time'),
|
'publish_time': ns.get('publish_time'),
|
||||||
'read_count': 0,
|
'read_count': 0,
|
||||||
|
|||||||
@ -14,14 +14,10 @@ async def news_article_search(ns={}):
|
|||||||
|
|
||||||
conditions = ["domain_name = '%s'" % domain_name, "del_flg = '0'"]
|
conditions = ["domain_name = '%s'" % domain_name, "del_flg = '0'"]
|
||||||
summary_conditions = ["domain_name = '%s'" % domain_name, "del_flg = '0'"]
|
summary_conditions = ["domain_name = '%s'" % domain_name, "del_flg = '0'"]
|
||||||
if ns.get('title_zh'):
|
if ns.get('title'):
|
||||||
conditions.append("title_zh like '%%%%%s%%%%'" % ns.get('title_zh'))
|
conditions.append("title like '%%%%%s%%%%'" % ns.get('title'))
|
||||||
if ns.get('title_en'):
|
if ns.get('article_type'):
|
||||||
conditions.append("title_en like '%%%%%s%%%%'" % ns.get('title_en'))
|
conditions.append("article_type = '%s'" % ns.get('article_type'))
|
||||||
if ns.get('article_type_zh'):
|
|
||||||
conditions.append("article_type_zh = '%s'" % ns.get('article_type_zh'))
|
|
||||||
if ns.get('article_type_en'):
|
|
||||||
conditions.append("article_type_en = '%s'" % ns.get('article_type_en'))
|
|
||||||
if ns.get('status'):
|
if ns.get('status'):
|
||||||
conditions.append("status = '%s'" % ns.get('status'))
|
conditions.append("status = '%s'" % ns.get('status'))
|
||||||
where_clause = " and ".join(conditions)
|
where_clause = " and ".join(conditions)
|
||||||
@ -31,46 +27,26 @@ async def news_article_search(ns={}):
|
|||||||
try:
|
try:
|
||||||
count_sql = """select count(*) as total_count from enterprise_news_article where %s;""" % where_clause
|
count_sql = """select count(*) as total_count from enterprise_news_article where %s;""" % where_clause
|
||||||
total_count = (await sor.sqlExe(count_sql, {}))[0]['total_count']
|
total_count = (await sor.sqlExe(count_sql, {}))[0]['total_count']
|
||||||
summary_zh_sql = """
|
summary_sql = """
|
||||||
select article_type_zh as article_type, count(*) as article_count,
|
select article_type, count(*) as article_count, ifnull(sum(read_count), 0) as read_count
|
||||||
ifnull(sum(read_count), 0) as read_count
|
|
||||||
from enterprise_news_article
|
from enterprise_news_article
|
||||||
where %s
|
where %s
|
||||||
and article_type_zh is not null and article_type_zh != ''
|
group by article_type;
|
||||||
group by article_type_zh;
|
|
||||||
""" % " and ".join(summary_conditions)
|
""" % " and ".join(summary_conditions)
|
||||||
summary_en_sql = """
|
summary_result = await sor.sqlExe(summary_sql, {})
|
||||||
select article_type_en as article_type, count(*) as article_count,
|
summary_mapping = {}
|
||||||
ifnull(sum(read_count), 0) as read_count
|
for summary_dic in summary_result:
|
||||||
from enterprise_news_article
|
summary_mapping[summary_dic.get('article_type')] = summary_dic
|
||||||
where %s
|
article_type_summary = []
|
||||||
and article_type_en is not null and article_type_en != ''
|
|
||||||
group by article_type_en
|
|
||||||
order by article_type_en;
|
|
||||||
""" % " and ".join(summary_conditions)
|
|
||||||
summary_zh_result = await sor.sqlExe(summary_zh_sql, {})
|
|
||||||
summary_en_result = await sor.sqlExe(summary_en_sql, {})
|
|
||||||
summary_zh_mapping = {}
|
|
||||||
for summary_dic in summary_zh_result:
|
|
||||||
summary_zh_mapping[summary_dic.get('article_type')] = summary_dic
|
|
||||||
article_type_summary_zh = []
|
|
||||||
for article_type in ['企业动态', '产品动态', '行业洞察', '活动资讯']:
|
for article_type in ['企业动态', '产品动态', '行业洞察', '活动资讯']:
|
||||||
summary_dic = summary_zh_mapping.get(article_type, {})
|
summary_dic = summary_mapping.get(article_type, {})
|
||||||
article_type_summary_zh.append({
|
article_type_summary.append({
|
||||||
'article_type': article_type,
|
'article_type': article_type,
|
||||||
'article_count': summary_dic.get('article_count', 0),
|
'article_count': summary_dic.get('article_count', 0),
|
||||||
'read_count': summary_dic.get('read_count', 0)
|
'read_count': summary_dic.get('read_count', 0)
|
||||||
})
|
})
|
||||||
article_type_summary_en = []
|
|
||||||
for summary_dic in summary_en_result:
|
|
||||||
article_type_summary_en.append({
|
|
||||||
'article_type': summary_dic.get('article_type'),
|
|
||||||
'article_count': summary_dic.get('article_count', 0),
|
|
||||||
'read_count': summary_dic.get('read_count', 0)
|
|
||||||
})
|
|
||||||
search_sql = """
|
search_sql = """
|
||||||
select id, domain_name, title_zh, title_en, article_type_zh, article_type_en,
|
select id, domain_name, title, article_type, summary, cover_img, status, content,
|
||||||
summary_zh, summary_en, cover_img, content_zh, content_en, status,
|
|
||||||
publish_time, read_count, update_time, create_at
|
publish_time, read_count, update_time, create_at
|
||||||
from enterprise_news_article
|
from enterprise_news_article
|
||||||
where %s
|
where %s
|
||||||
@ -85,8 +61,7 @@ async def news_article_search(ns={}):
|
|||||||
'status': True,
|
'status': True,
|
||||||
'msg': 'search news article success',
|
'msg': 'search news article success',
|
||||||
'data': result,
|
'data': result,
|
||||||
'article_type_summary_zh': article_type_summary_zh,
|
'article_type_summary': article_type_summary,
|
||||||
'article_type_summary_en': article_type_summary_en,
|
|
||||||
'pagination': {
|
'pagination': {
|
||||||
'total': total_count,
|
'total': total_count,
|
||||||
'page_size': page_size,
|
'page_size': page_size,
|
||||||
|
|||||||
@ -8,14 +8,21 @@ async def news_article_update(ns={}):
|
|||||||
ns_dic = {
|
ns_dic = {
|
||||||
'id': ns.get('id')
|
'id': ns.get('id')
|
||||||
}
|
}
|
||||||
for field in [
|
if 'title' in ns:
|
||||||
'title_zh', 'title_en', 'article_type_zh', 'article_type_en',
|
ns_dic['title'] = ns.get('title')
|
||||||
'summary_zh', 'summary_en', 'content_zh', 'content_en'
|
if 'article_type' in ns:
|
||||||
]:
|
# if ns.get('article_type') not in ['企业动态', '产品动态', '行业洞察', '活动资讯']:
|
||||||
if field in ns:
|
# return {
|
||||||
ns_dic[field] = ns.get(field)
|
# 'status': False,
|
||||||
|
# 'msg': '文章类型错误'
|
||||||
|
# }
|
||||||
|
ns_dic['article_type'] = ns.get('article_type')
|
||||||
|
if 'summary' in ns:
|
||||||
|
ns_dic['summary'] = ns.get('summary')
|
||||||
if 'cover_img' in ns:
|
if 'cover_img' in ns:
|
||||||
ns_dic['cover_img'] = ns.get('cover_img')
|
ns_dic['cover_img'] = ns.get('cover_img')
|
||||||
|
if 'content' in ns:
|
||||||
|
ns_dic['content'] = ns.get('content')
|
||||||
if 'status' in ns:
|
if 'status' in ns:
|
||||||
if ns.get('status') not in ['0', '1']:
|
if ns.get('status') not in ['0', '1']:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,187 +0,0 @@
|
|||||||
# Bilingual Enterprise News Implementation Plan
|
|
||||||
|
|
||||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
||||||
|
|
||||||
**Goal:** Update enterprise news APIs to store, filter, and return Chinese and English article fields without maintaining legacy content fields.
|
|
||||||
|
|
||||||
**Architecture:** Keep the existing DSPY endpoint structure and database table. Add and update endpoints write the eight language-specific columns; search and detail endpoints return those columns directly. Shared publication, image, date, status, and read-count behavior remains unchanged.
|
|
||||||
|
|
||||||
**Tech Stack:** DSPY Python endpoints, async DBPools/sor database access, MySQL.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Task 1: Add and update bilingual content
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `b/news/news_article_add.dspy`
|
|
||||||
- Modify: `b/news/news_article_update.dspy`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Update add validation**
|
|
||||||
|
|
||||||
Replace the legacy `title` requirement with:
|
|
||||||
|
|
||||||
```python
|
|
||||||
if not ns.get('title_zh'):
|
|
||||||
return {
|
|
||||||
'status': False,
|
|
||||||
'msg': '请传递中文标题'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: Update add insert fields**
|
|
||||||
|
|
||||||
Write these fields in `ns_dic`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
'title_zh': ns.get('title_zh'),
|
|
||||||
'title_en': ns.get('title_en'),
|
|
||||||
'article_type_zh': ns.get('article_type_zh'),
|
|
||||||
'article_type_en': ns.get('article_type_en'),
|
|
||||||
'summary_zh': ns.get('summary_zh'),
|
|
||||||
'summary_en': ns.get('summary_en'),
|
|
||||||
'content_zh': ns.get('content_zh'),
|
|
||||||
'content_en': ns.get('content_en'),
|
|
||||||
```
|
|
||||||
|
|
||||||
Do not write `title`, `article_type`, `summary`, or `content`.
|
|
||||||
|
|
||||||
- [ ] **Step 3: Update editable fields**
|
|
||||||
|
|
||||||
In `news_article_update.dspy`, loop through the eight bilingual fields and copy only keys present in `ns`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
for field in [
|
|
||||||
'title_zh', 'title_en', 'article_type_zh', 'article_type_en',
|
|
||||||
'summary_zh', 'summary_en', 'content_zh', 'content_en'
|
|
||||||
]:
|
|
||||||
if field in ns:
|
|
||||||
ns_dic[field] = ns.get(field)
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 4: Verify static diagnostics**
|
|
||||||
|
|
||||||
Run IDE lint diagnostics for both files. Expected: no new errors.
|
|
||||||
|
|
||||||
### Task 2: Update backend search and detail
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `b/news/news_article_search.dspy`
|
|
||||||
- Verify: `b/news/news_article_detail.dspy`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Add bilingual filters**
|
|
||||||
|
|
||||||
Build optional conditions for exact type matching and fuzzy title matching:
|
|
||||||
|
|
||||||
```python
|
|
||||||
if ns.get('title_zh'):
|
|
||||||
conditions.append("title_zh like '%%%%%s%%%%'" % ns.get('title_zh'))
|
|
||||||
if ns.get('title_en'):
|
|
||||||
conditions.append("title_en like '%%%%%s%%%%'" % ns.get('title_en'))
|
|
||||||
if ns.get('article_type_zh'):
|
|
||||||
conditions.append("article_type_zh = '%s'" % ns.get('article_type_zh'))
|
|
||||||
if ns.get('article_type_en'):
|
|
||||||
conditions.append("article_type_en = '%s'" % ns.get('article_type_en'))
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 2: Return bilingual list fields**
|
|
||||||
|
|
||||||
Select:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
id, domain_name,
|
|
||||||
title_zh, title_en,
|
|
||||||
article_type_zh, article_type_en,
|
|
||||||
summary_zh, summary_en,
|
|
||||||
content_zh, content_en,
|
|
||||||
cover_img, status, publish_time, read_count, update_time, create_at
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 3: Return bilingual type summaries**
|
|
||||||
|
|
||||||
Aggregate Chinese and English article types separately and return:
|
|
||||||
|
|
||||||
```python
|
|
||||||
'article_type_summary_zh': article_type_summary_zh,
|
|
||||||
'article_type_summary_en': article_type_summary_en,
|
|
||||||
```
|
|
||||||
|
|
||||||
Each item keeps `article_type`, `article_count`, and `read_count`.
|
|
||||||
|
|
||||||
- [ ] **Step 4: Verify backend detail**
|
|
||||||
|
|
||||||
`news_article_detail.dspy` already uses `select *`; confirm it returns the new columns without changing publication behavior.
|
|
||||||
|
|
||||||
- [ ] **Step 5: Verify static diagnostics**
|
|
||||||
|
|
||||||
Run IDE lint diagnostics for backend search and detail. Expected: no new errors.
|
|
||||||
|
|
||||||
### Task 3: Update frontend search and detail
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Modify: `b/news/front_news_search.dspy`
|
|
||||||
- Modify: `b/news/front_news_detail.dspy`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Add bilingual frontend filters**
|
|
||||||
|
|
||||||
Support `title_zh`, `title_en`, `article_type_zh`, and `article_type_en` using the same matching rules as backend search.
|
|
||||||
|
|
||||||
- [ ] **Step 2: Return bilingual frontend list fields**
|
|
||||||
|
|
||||||
Select:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
id, title_zh, title_en, article_type_zh, article_type_en,
|
|
||||||
summary_zh, summary_en, cover_img, publish_time, read_count
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 3: Return bilingual frontend detail fields**
|
|
||||||
|
|
||||||
After incrementing `read_count`, select:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
id, title_zh, title_en, article_type_zh, article_type_en,
|
|
||||||
summary_zh, summary_en, cover_img, content_zh, content_en,
|
|
||||||
publish_time, read_count
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 4: Verify publication and read-count behavior**
|
|
||||||
|
|
||||||
Confirm both frontend queries retain `status = '1' AND del_flg = '0'`, and detail still increments `read_count` once.
|
|
||||||
|
|
||||||
- [ ] **Step 5: Verify static diagnostics**
|
|
||||||
|
|
||||||
Run IDE lint diagnostics for both frontend files. Expected: no new errors.
|
|
||||||
|
|
||||||
### Task 4: Final verification
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- Verify: `b/news/news_article_add.dspy`
|
|
||||||
- Verify: `b/news/news_article_update.dspy`
|
|
||||||
- Verify: `b/news/news_article_search.dspy`
|
|
||||||
- Verify: `b/news/news_article_detail.dspy`
|
|
||||||
- Verify: `b/news/front_news_search.dspy`
|
|
||||||
- Verify: `b/news/front_news_detail.dspy`
|
|
||||||
|
|
||||||
- [ ] **Step 1: Check legacy-field removal**
|
|
||||||
|
|
||||||
Search the six endpoints for writes or selected output fields named exactly `title`, `article_type`, `summary`, or `content`. Expected: none except comments or compatibility-neutral code.
|
|
||||||
|
|
||||||
- [ ] **Step 2: Check diff scope**
|
|
||||||
|
|
||||||
Run:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
git diff -- b/news
|
|
||||||
```
|
|
||||||
|
|
||||||
Expected: only the requested bilingual endpoint changes plus the user's existing SQL schema update.
|
|
||||||
|
|
||||||
- [ ] **Step 3: Check whitespace**
|
|
||||||
|
|
||||||
Run:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
git diff --check -- b/news
|
|
||||||
```
|
|
||||||
|
|
||||||
Expected: no output and exit code 0.
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
# 中英文企业动态接口设计
|
|
||||||
|
|
||||||
## 目标
|
|
||||||
|
|
||||||
企业文章支持运营同时录入中文和英文内容。接口直接使用
|
|
||||||
`enterprise_news_article` 表中的中英文字段,不再读写旧字段
|
|
||||||
`title`、`article_type`、`summary`、`content`。
|
|
||||||
|
|
||||||
## 字段
|
|
||||||
|
|
||||||
- 中文:`title_zh`、`article_type_zh`、`summary_zh`、`content_zh`
|
|
||||||
- 英文:`title_en`、`article_type_en`、`summary_en`、`content_en`
|
|
||||||
- 共用:`cover_img`、`status`、`publish_time`、`read_count`
|
|
||||||
|
|
||||||
新增文章仅要求 `title_zh` 必填,其余中英文字段允许为空。
|
|
||||||
|
|
||||||
## 接口调整
|
|
||||||
|
|
||||||
- `news_article_add.dspy`:接收并写入全部中英文字段。
|
|
||||||
- `news_article_update.dspy`:按传入字段更新中英文内容。
|
|
||||||
- `news_article_search.dspy`:支持中英文标题和类型筛选,返回全部中英文字段;类型汇总分别使用中英文类型。
|
|
||||||
- `news_article_detail.dspy`:返回全部中英文字段。
|
|
||||||
- `front_news_search.dspy`:支持中英文标题和类型筛选,返回全部中英文字段。
|
|
||||||
- `front_news_detail.dspy`:返回全部中英文字段,并保持阅读量加一。
|
|
||||||
|
|
||||||
发布、下架、删除接口不涉及语言字段,不调整。
|
|
||||||
|
|
||||||
## 兼容边界
|
|
||||||
|
|
||||||
旧字段已由数据库移除非空约束,本次接口不再维护旧字段。调用方需要改为传入和读取中英文新字段。
|
|
||||||
|
|
||||||
## 验证
|
|
||||||
|
|
||||||
- 新增时缺少 `title_zh` 返回校验错误。
|
|
||||||
- 新增、更新后详情能完整返回中英文字段。
|
|
||||||
- 后台和前端列表能按中英文标题、类型筛选。
|
|
||||||
- 前端详情仍仅允许读取已发布文章,并正确增加阅读量。
|
|
||||||
Loading…
x
Reference in New Issue
Block a user