From 51f3b9241c7e70a022072c83f1c99653b28c6f03 Mon Sep 17 00:00:00 2001 From: xiaji Date: Mon, 12 Jan 2026 16:37:10 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E7=94=A8=E8=84=9A=E6=9C=AC=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E6=96=B0=E6=9B=B4=E6=96=B0=E4=BA=86=E5=88=86=E6=94=AF?= =?UTF-8?q?=E6=9C=BA=E6=9E=84=E6=89=80=E5=9C=A8=E7=9A=84=E8=90=A5=E4=B8=9A?= =?UTF-8?q?=E9=83=A8=E7=9A=84=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fzjgact/db.sqlite3 | Bin 471040 -> 471040 bytes .../management/commands/update_provinces.py | 126 ++++++++++++++++++ update_provinces.py | 74 ---------- 3 files changed, 126 insertions(+), 74 deletions(-) create mode 100644 fzjgact/huodong/management/commands/update_provinces.py delete mode 100644 update_provinces.py diff --git a/fzjgact/db.sqlite3 b/fzjgact/db.sqlite3 index 2eb1374d477ae62ca8c178b6783c5f62a2648de5..8ff1dd06befc64e8458f12884e7871a8f8731f72 100644 GIT binary patch delta 5152 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 V&d9SnQgZD%_KXZIM&$>>{t3PCSmXcz delta 2940 zcmYjT3se+G7VVzye$5Qs(}41sfDD6R2r6Kr0*Z=)DC!!;FCYqj;x}>eujmRhfS?9J zBjpdpvx4BtPmUI9)K&MK7&oi&Y&P+11WjZHX5)8tvwn6xTUG66=bY}-RqxfS`)=L$ zYVz*{<=+V^f6pv+avZmkJelO-D;7|0{wjwrFuPr@1) zfn_f#hewHr`C};9N4o2o0wW*}20$eAKGj3A2*^^)N8%(u>0-R;Yq62jUT9CX2fMtg z{czYM=@E}Z(xfGZUHM)yxN)kKHr|VD{pPoVd`!UJkNA6abLM zsr{-w*6wLt+Rs|Mhlqo`;7cu|yx4gH5&M#Pl9z0m>8iFUkQN^ z#maE_MI>SRpsHJf4VwlFFN^`++;^O|UrRCjs$rflO^=MvjDtL0>A=DSB>rCVJ374w z7*I%! z!6H7?v8I=a>ua%Y=@IDbps z!fdz-tKVm#l{qXl8axNCs&>CVj3mcMy5!&!8{XCjf3YEKAZa0*ol=UM`R^IAdeW1uG=MA;>h;LIPWJxzJ? zdH71I5myUC`8!-HQEz|Q(KD7M*|-=&rJ6ElOB24i7?$w1nS#1+-cx%0G}upeDe$vTwjgqXF!+i znA)EiZl@80`|ugpp6%E;1?qXd8}Kold4oDudC!z-93wxFZizObpCOWuY0dTW;njk* z$$CZtg_c`Gs>ofn(|KY)dbtv=%LSX0s2SZ@MUJw|amcx&89iGCHNzyK8}Wh-RWAZS^^4$@>JZ|HG2BwbQqLbN*p$xG+ubJ$TnFmh z=gRTj1*9*AP)RD>GS2)!-K(UVo*OrL%z_RnNlX$F3?jFT$Z|r2!*{BQi?vva#*=+q zxW##(l@@(VOLuuqXWKrvqfVd184ma@FWU!A(OE5|1;X5MY!R4wL7Zeli?={2s!k>C zxoRtDXjX${LOUjaj4qczyjrm7W5$6)qbYfh6G_{vYM>PzSqk6V0w%IvT{MFNVe{|m zfDLijR@lJX@+Rnhy@+3T%>`1sZ~gQkzO)Upcr>~gB8_gxIakXeXLU1LR}A-6`}%Q| zRZC$Wg)lNsAc8C@Cr)_U=a9g^0{0ZIhPpO9yE`I3#lOCn#y4b`gSxJ(b)l#omc!{W%K)aUG@ zouaJPjp|U}eem3tp22o2Os7%U{JSV@h{x_HT~M{l=@hQj;ZMU1kckYtx3O#C;Q{zN zm}fG&uUC&!B~Ebx@U~$8ACnG|5-=fX;LKiPVvL2%gAx+jLg^njOLf zs>*mf{2HXfUCsz4oF=Q6l*^vqnC=_%JZj`4F0}U`pS+!87mbHWE6mr6D zM+HscRResZ7Hs^4bvy^_Jx$@{--vtn1=oqa$a)lR$o7~8EbkkQ5b+we@myP6Z zA4uAV4=omlh3HJrYR!Ch*8ey2E>D&=YN>%APBnv=?P1XTIc=ln-|C(3sbPPs?DqN} D6cXrO diff --git a/fzjgact/huodong/management/commands/update_provinces.py b/fzjgact/huodong/management/commands/update_provinces.py new file mode 100644 index 0000000..d191f56 --- /dev/null +++ b/fzjgact/huodong/management/commands/update_provinces.py @@ -0,0 +1,126 @@ +from django.core.management.base import BaseCommand +from openai import OpenAI +from huodong.models import Branch +import time +import re + + +class Command(BaseCommand): + help = 'Update branch provinces using AI API' + + def handle(self, *args, **options): + client = OpenAI( + base_url="https://integrate.api.nvidia.com/v1", + api_key="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" + ) + + def get_correct_province(branch_name, current_location, retry_count=0): + prompt = f"""请根据以下分支机构名称,返回一个正确的中国省份名称(全称,如:浙江省、北京市、上海市、广东省等)。 + +分支机构名称:{branch_name} + +要求: +1. 只返回省份名称,不要包含任何其他文字 +2. 省份名称必须是中国的省级行政区全称 +3. 如果无法确定,返回None +例子一: +分支机构名称:石家庄中山西路营业部 +返回:河北省 +例子二: +分支机构名称:北京市海淀区营业部 +返回:北京市 +例子三: +分支机构名称:奎屯北京东路营业部 +返回:新疆维吾尔自治区 + +""" + + + try: + completion = client.chat.completions.create( + model="deepseek-ai/deepseek-r1", + messages=[{"role": "user", "content": prompt}], + temperature=0.3, + top_p=0.7, + max_tokens=100, + stream=False + ) + + message = completion.choices[0].message + reasoning = getattr(message, "reasoning_content", None) + content = message.content + + if reasoning: + self.stdout.write(f" 推理过程: {reasoning[:200]}...") + + if content is None: + if reasoning: + self.stdout.write(f" content为None,尝试从推理过程提取...") + + patterns = [ + r'(?:正确的(?:答案)?应该是|所以|因此|答案是|结果为)[::\s]*(北京市|天津市|上海市|重庆市|河北省|山西省|辽宁省|吉林省|黑龙江省|江苏省|浙江省|安徽省|福建省|江西省|山东省|河南省|湖北省|湖南省|广东省|海南省|四川省|贵州省|云南省|陕西省|甘肃省|青海省|台湾省|内蒙古自治区|广西壮族自治区|西藏自治区|宁夏回族自治区|新疆维吾尔自治区|香港特别行政区|澳门特别行政区)', + r'(北京市|天津市|上海市|重庆市|河北省|山西省|辽宁省|吉林省|黑龙江省|江苏省|浙江省|安徽省|福建省|江西省|山东省|河南省|湖北省|湖南省|广东省|海南省|四川省|贵州省|云南省|陕西省|甘肃省|青海省|台湾省|内蒙古自治区|广西壮族自治区|西藏自治区|宁夏回族自治区|新疆维吾尔自治区|香港特别行政区|澳门特别行政区)' + ] + + for pattern in patterns: + match = re.search(pattern, reasoning) + if match: + result = match.group(1) + self.stdout.write(f" 从推理提取结果: {result}") + return result + + if retry_count < 2: + self.stdout.write(f" content为None,重试中 ({retry_count + 1}/2)...") + time.sleep(2) + return get_correct_province(branch_name, current_location, retry_count + 1) + else: + self.stdout.write(self.style.WARNING(f" 多次重试后仍无结果,使用当前省份")) + return current_location + + result = content.strip() + self.stdout.write(f" 原始结果: {result}") + + return result + + except Exception as e: + if retry_count < 2: + self.stdout.write(self.style.WARNING(f" API调用失败: {e},重试中 ({retry_count + 1}/2)...")) + time.sleep(2) + return get_correct_province(branch_name, current_location, retry_count + 1) + else: + self.stdout.write(self.style.ERROR(f" 多次重试后仍失败: {e},使用当前省份")) + return current_location + + branches = Branch.objects.all() + total = branches.count() + updated_count = 0 + + self.stdout.write(self.style.SUCCESS(f"开始处理 {total} 个分支机构...")) + self.stdout.write("=" * 80) + + for index, branch in enumerate(branches, 1): + self.stdout.write(f"\n[{index}/{total}] 处理: {branch.name}") + self.stdout.write(f"当前省份: {branch.location}") + + try: + correct_province = get_correct_province(branch.name, branch.location) + self.stdout.write(f"建议省份: {correct_province}") + + if correct_province != branch.location: + old_location = branch.location + branch.location = correct_province + branch.save() + self.stdout.write(self.style.SUCCESS(f"✓ 已更新: {old_location} -> {correct_province}")) + updated_count += 1 + else: + self.stdout.write("- 省份未变化") + + except Exception as e: + self.stdout.write(self.style.ERROR(f"✗ 处理失败: {e}")) + + self.stdout.write("-" * 80) + + self.stdout.write(self.style.SUCCESS(f"\n处理完成!")) + self.stdout.write(f"总计: {total} 个分支机构") + self.stdout.write(f"已更新: {updated_count} 个") + self.stdout.write(f"未变化: {total - updated_count} 个") diff --git a/update_provinces.py b/update_provinces.py deleted file mode 100644 index e5d1874..0000000 --- a/update_provinces.py +++ /dev/null @@ -1,74 +0,0 @@ -from openai import OpenAI -from fzjgact.huodong.models import Branch - -client = OpenAI( - base_url="https://integrate.api.nvidia.com/v1", - api_key="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" -) - -def get_correct_province(branch_name, current_location): - prompt = f"""请根据以下分支机构名称,返回一个正确的中国省份名称(全称,如:浙江省、北京市、上海市、广东省等)。 - -分支机构名称:{branch_name} -当前省份:{current_location} - -要求: -1. 只返回省份名称,不要包含任何其他文字 -2. 省份名称必须是中国的省级行政区全称 -3. 如果无法确定,返回当前省份名称""" - - completion = client.chat.completions.create( - model="deepseek-ai/deepseek-r1", - messages=[{"role": "user", "content": prompt}], - temperature=0.3, - top_p=0.7, - max_tokens=100, - stream=False - ) - - reasoning = getattr(completion.choices[0].message, "reasoning_content", None) - if reasoning: - print(f"推理过程: {reasoning}") - - result = completion.choices[0].message.content.strip() - print(f"原始结果: {result}") - - return result - -def update_branch_provinces(): - branches = Branch.objects.all() - total = branches.count() - updated_count = 0 - - print(f"开始处理 {total} 个分支机构...") - print("=" * 80) - - for index, branch in enumerate(branches, 1): - print(f"\n[{index}/{total}] 处理: {branch.name}") - print(f"当前省份: {branch.location}") - - try: - correct_province = get_correct_province(branch.name, branch.location) - print(f"建议省份: {correct_province}") - - if correct_province != branch.location: - old_location = branch.location - branch.location = correct_province - branch.save() - print(f"✓ 已更新: {old_location} -> {correct_province}") - updated_count += 1 - else: - print("- 省份未变化") - - except Exception as e: - print(f"✗ 处理失败: {e}") - - print("-" * 80) - - print(f"\n处理完成!") - print(f"总计: {total} 个分支机构") - print(f"已更新: {updated_count} 个") - print(f"未变化: {total - updated_count} 个") - -if __name__ == "__main__": - update_branch_provinces()