仿BOSS招聘平臺實現(xiàn)(5)
管理者端-查詢企業(yè)列表apis層enterprise_router.get(/list, summary查詢企業(yè)列表, description查詢企業(yè)列表) async def select_enterprise_list(page: int Query(1, title頁碼, description頁碼, ge1), page_size: int Query(10, title每頁數(shù)量, description每頁數(shù)量, ge10, le50), enterprise_name: str Query(None, title企業(yè)名稱, description企業(yè)名稱), submit_time_start: str Query(None, title提交時間開始, description提交時間開始), submit_time_end: str Query(None, title提交時間結(jié)束, description提交時間結(jié)束) ): resawait EnterpriseService.select_enterprise_list(page,page_size,enterprise_name,submit_time_start,submit_time_end) return { code: 1, message: 查詢成功, data: res }GET /list就是一個帶篩選的分頁查詢。分頁參數(shù)page/page_size走Query還加了邊界page最小 1page_size卡在 10~50 之間——這等于硬性規(guī)定每頁至少 10 條、最多 50 條前端想一次拉 100 條是拉不到的。enterprise_name和起止時間都是可選篩選條件None表示不篩。路由本身不碰數(shù)據(jù)庫把參數(shù)原樣丟給 Service回來包成{code, message, data}返回。services層staticmethod async def select_enterprise_list(page: int, page_size: int, enterprise_name: str, submit_time_start: str, submit_time_end: str): queryEnterprise.all() if enterprise_name: queryquery.filter(enterprise_name__containsenterprise_name) if submit_time_start: queryquery.filter(submit_time__gtesubmit_time_start) if submit_time_end: queryquery.filter(submit_time__ltesubmit_time_end) total_countawait query.count() total_pagemath.ceil(total_count/page_size) query await query.offset((page-1)*page_size).limit(page_size) enterprise_list [] for enterprise in query: enterprise_id enterprise.id enterpriseinfo await EnterpriseInfo.get_or_none(enterprise_identerprise_id).prefetch_related(industry) enterprise_qualificationawait EnterpriseQualification.get_or_none(enterprise_identerprise_id) enterprise_reviewawait EnterpriseReview.get_or_none(enterprise_identerprise_id) if enterpriseinfo and enterpriseinfo.industry: industry_name enterpriseinfo.industry.name else: industry_name None res_dict{ enterprise:enterprise, enterpriseinfo:enterpriseinfo, enterprise_qualification:enterprise_qualification, enterprise_review:enterprise_review, industry:industry_name } enterprise_list.append(res_dict) return { total_count: total_count, total_page: total_page, page: page, page_size: page_size, enterprise_list: enterprise_list }先把查詢條件動態(tài)拼上去有企業(yè)名就按contains模糊匹配填了起止時間就按submit_time區(qū)間過濾。剩下的交給count算出總數(shù)再用math.ceil算總頁數(shù)total_count / page_size向上取整避免出現(xiàn)半頁算不出的情況。分頁用的是offset((page-1)*page_size).limit(page_size)——也就是跳過前面幾頁只取當(dāng)前頁那幾條。真正的重頭戲在for循環(huán)里每家企業(yè)要把它的工商信息、資質(zhì)、審核記錄三張表都撈出來拼一起行業(yè)名稱從industry關(guān)聯(lián)里取取不到就填None。最后返回的不只是列表還把總數(shù)、總頁數(shù)、當(dāng)前頁碼、每頁大小都帶回去前端做分頁條直接用。管理者端-企業(yè)詳情enterprise_router.get(/detail/{enterprise_id}, summary查詢企業(yè)詳情, description查詢企業(yè)詳情) async def select_enterprise_by_id(enterprise_id: int): resawait EnterpriseService.select_enterprise_by_id(enterprise_id) return { code: 1, message: 查詢成功, data: res } staticmethod async def select_enterprise_by_id(enterprise_id: int): enterpriseawait Enterprise.get_or_none(identerprise_id) if not enterprise: raise Exception(企業(yè)不存在) enterpriseinfo await EnterpriseInfo.get(enterprise_identerprise_id).prefetch_related(industry) enterprise_qualificationawait EnterpriseQualification.get_or_none(enterprise_identerprise_id) enterprise_reviewawait EnterpriseReview.get_or_none(enterprise_identerprise_id) return { enterprise:enterprise, enterpriseinfo:enterpriseinfo, enterprise_qualification:enterprise_qualification, enterprise_review:enterprise_review, industry:enterpriseinfo.industry.name }先按 id 找企業(yè)主體找不到直接報錯。然后一次性把工商信息順帶把industry關(guān)聯(lián)預(yù)加載出來省得后面再查一次、資質(zhì)、審核記錄都查出來拼成同一個結(jié)構(gòu)返回。跟列表不一樣的地方這里工商信息用的是EnterpriseInfo.get(...)不是get_or_none意味著它默認(rèn)這家企業(yè)一定有對應(yīng)的工商信息末尾enterpriseinfo.industry.name也是直接取沒做空判斷。所以這段代碼隱含一個前提——能進審核流程的企業(yè)industry一定存在。管理者端-企業(yè)狀態(tài)審核enterprise_router.post(/review, summary企業(yè)審核, description企業(yè)審核) async def enterprise_review(enterpriseReviewCreateRequest: EnterpriseReviewCreateRequest): await EnterpriseService.enterprise_review(enterpriseReviewCreateRequest) return { code: 1, message: 審核成功 } staticmethod async def enterprise_review(enterpriseReviewCreateRequest: EnterpriseReviewCreateRequest): enterprise_identerpriseReviewCreateRequest.enterprise_id enterprise_reviewawait EnterpriseReview.get_or_none(enterprise_identerprise_id) if enterprise_review is None: await EnterpriseReview.create( enterprise_identerprise_id, review_resultenterpriseReviewCreateRequest.review_result, review_reasonenterpriseReviewCreateRequest.review_reason, remarkenterpriseReviewCreateRequest.remark, review_timenow() ) else: enterprise_review.review_resultenterpriseReviewCreateRequest.review_result if enterpriseReviewCreateRequest.review_result else enterprise_review.review_result enterprise_review.review_reasonenterpriseReviewCreateRequest.review_reason if enterpriseReviewCreateRequest.review_reason else enterprise_review.review_reason enterprise_review.remarkenterpriseReviewCreateRequest.remark if enterpriseReviewCreateRequest.remark else enterprise_review.remark enterprise_review.review_timenow() await enterprise_review.save() if enterpriseReviewCreateRequest.review_result1: enterpriseawait Enterprise.get_or_none(identerprise_id) enterprise.account_statusAccountStatus.NORMAL await enterprise.save()審核記錄一企一條所以先按enterprise_id查有沒有沒有就新建填上結(jié)果、理由、備注和審核時間已經(jīng)有了就走更新分支——注意那個新值 if 新值 else 舊值的寫法意思是前端沒傳空值的字段就不覆蓋庫里原來的值只改傳了的。不管新建還是更新審核時間都刷新成當(dāng)下。最后if review_result 1是關(guān)鍵聯(lián)動審核通過1才把企業(yè)的account_status置為NORMAL正常企業(yè)這下才能真正登錄使用。審核不通過review_result不是 1就不動賬號狀態(tài)企業(yè)繼續(xù)卡在待審核。企業(yè)端-登錄enterprise_router.post(/login, summary企業(yè)登錄, description企業(yè)登錄) async def login(loginMobileRequest: LoginMobileRequest): resawait EnterpriseService.login(loginMobileRequest) return { code: 1, message: 登錄成功, data: res } staticmethod async def login(loginMobileRequest: LoginMobileRequest): enterprise_qualifications await EnterpriseQualification.filter(contact_phoneloginMobileRequest.mobile) if enterprise_qualifications is None: raise Exception(手機號不存在) for enterprise_qualification in enterprise_qualifications: enterprise_identerprise_qualification.enterprise_id enterprise_reviewawait EnterpriseReview.get_or_none(enterprise_identerprise_id) if enterprise_review.review_result 1: key fboss-api:enterprise-login:sms:{loginMobileRequest.mobile} redis_coderedis_client.get(key) if redis_code is None: raise Exception(驗證碼已過期) if redis_code ! loginMobileRequest.code: raise Exception(驗證碼錯誤) access_token,refresh_tokencreate_tokens(str(enterprise_id),loginMobileRequest.mobile) redis_client.delete(key) return { enterprise_access_token: access_token, enterprise_refresh_token: refresh_token, } raise Exception(登錄失敗)先用手機號去EnterpriseQualification表里找對應(yīng)的企業(yè)資質(zhì)記錄。手機號沒匹配到時for循環(huán)一次都不執(zhí)行最后落到raise Exception(登錄失敗)。接著for循環(huán)一個手機號理論上可能關(guān)聯(lián)多個企業(yè)代碼留了這個口子所以逐個看。只有當(dāng)這家企業(yè)審核通過了review_result 1才讓它登錄。登錄時去 Redis 按手機號取之前發(fā)的短信驗證碼取不到說明過期了對不上說明輸錯了。都過了才發(fā)access_token/refresh_token發(fā)完順手把 Redis 里的驗證碼刪掉一次性憑證不能重復(fù)使用。最后要是循環(huán)走完沒一家滿足就拋登錄失敗。

相關(guān)新聞

STM32 GPIO八種工作模式詳解:從點燈到按鍵狀態(tài)機實戰(zhàn)

STM32 GPIO八種工作模式詳解:從點燈到按鍵狀態(tài)機實戰(zhàn)

1. 從點燈開始:為什么GPIO是STM32的“第一課”如果你剛拿到一塊STM32開發(fā)板,或者從51單片機、Arduino轉(zhuǎn)過來,第一個要跑的程序十有八九是點燈。這幾乎成了嵌入式開發(fā)界的“Hello World”。但很多人可能沒細(xì)想,為什么偏偏是點燈&am…

2026/7/29 3:56:02 閱讀更多
MicroPython模塊1.2.6解析:從核心機制到硬件驅(qū)動實戰(zhàn)

MicroPython模塊1.2.6解析:從核心機制到硬件驅(qū)動實戰(zhàn)

1. 項目概述:從“模塊”到“生態(tài)”的認(rèn)知升級當(dāng)你第一次在MicroPython的官方文檔或GitHub倉庫里看到“MicroPython模塊 1.2.6”這個標(biāo)題時,可能會覺得這只是一個普通的版本更新日志。但如果你像我一樣,在嵌入式開發(fā)和物聯(lián)網(wǎng)領(lǐng)域摸爬滾打了十幾…

2026/7/29 3:46:02 閱讀更多
2026論文翻車真相[特殊字符]不是你不會寫,是工具選錯了!okbiye才是隱形通關(guān)密碼?

2026論文翻車真相[特殊字符]不是你不會寫,是工具選錯了!okbiye才是隱形通關(guān)密碼?

🌐 官方直達(dá):首頁 - Okbiye智能寫作Okbiye免費論文查重檢測-首款免費論文檢測軟件,為畢業(yè)生提供專業(yè)的論文重復(fù)率檢測、論文降重、Aigc檢測、智能排版 、論文寫作等一站式服務(wù)。https://www.okbiye.com 同樣是寫畢業(yè)論文,為什么有的人一次查…

2026/7/29 8:26:10 閱讀更多
HDCP版權(quán)保護_橋接芯片科普05

HDCP版權(quán)保護_橋接芯片科普05

HDCP 版權(quán)保護:橋接芯片里最容易被忽視的"隱形門禁" 龍迅橋接芯片科普系列 第 05 篇 系列文章:01 選型指南 | 02 DSC 顯示流壓縮 | 03 車載顯示橋接方案 | 04 Type-C 擴展塢 | 05 HDCP 版權(quán)保護 | 06 D-PHY vs C-PHY(待寫&#xf…

2026/7/29 8:26:10 閱讀更多
3D打印與Arduino結(jié)合:從零打造會跳舞的仿生機器人

3D打印與Arduino結(jié)合:從零打造會跳舞的仿生機器人

1. 項目概述:當(dāng)3D打印遇上Arduino,一個會跳舞的機器人誕生了 如果你和我一樣,既沉迷于3D打印機“無中生有”的魔力,又對Arduino開源硬件控制現(xiàn)實世界的能力著迷,那么“精舞堂BOB”這個項目絕對能讓你兩眼放光。這不僅僅…

2026/7/29 8:26:10 閱讀更多
基于ESP32-S3的3D裸眼風(fēng)扇:從視覺暫留原理到無線智能顯示實戰(zhàn)

基于ESP32-S3的3D裸眼風(fēng)扇:從視覺暫留原理到無線智能顯示實戰(zhàn)

1. 項目概述:從“風(fēng)扇”到“空中畫師”的蛻變 最近在創(chuàng)客圈和極客社區(qū)里,一個老項目又火了起來,那就是“3D裸眼風(fēng)扇”。你可能在商場、科技展或者短視頻里見過它:一個高速旋轉(zhuǎn)的扇葉上,排列著一圈LED燈,當(dāng)它…

2026/7/29 8:16:09 閱讀更多
面試官大笑:“一個任務(wù)拆給 5 個 Subagent 并行跑,不比 1 個快 5 倍?“我搖頭:“快不了,還可能更慢“

面試官大笑:“一個任務(wù)拆給 5 個 Subagent 并行跑,不比 1 個快 5 倍?“我搖頭:“快不了,還可能更慢“

前兩個月,我在重構(gòu) AlgoMooc 網(wǎng)站過程中,發(fā)現(xiàn)一個問題:在 Claude Code 里把一個任務(wù)拆給 5 個 Subagent 并行跑,結(jié)果可能比 1 個 agent 從頭干到尾還慢? 大多數(shù)人的第一反應(yīng)是反過來的:活是并行干的&#…

2026/7/29 0:15:24 閱讀更多
# 鴻蒙 HarmonyOS 應(yīng)用開發(fā)實戰(zhàn)(第25期)|骰子(Dice Roller)— Unicode 符號與動畫渲染精講

# 鴻蒙 HarmonyOS 應(yīng)用開發(fā)實戰(zhàn)(第25期)|骰子(Dice Roller)— Unicode 符號與動畫渲染精講

一、應(yīng)用概述 骰子(Dice Roller) 是一款經(jīng)典的休閑娛樂應(yīng)用,模擬了真實擲骰子的過程。應(yīng)用投擲兩個骰子(六面標(biāo)準(zhǔn)骰),使用 Unicode 骰面符號直觀展示每個骰子的點數(shù),并伴有快速滾動的動畫效果?!?/p>

2026/7/29 0:15:24 閱讀更多