仿BOSS招聘平臺(tái)實(shí)現(xiàn)(5)
管理者端-查詢企業(yè)列表apis層enterprise_router.get(/list, summary查詢企業(yè)列表, description查詢企業(yè)列表) async def select_enterprise_list(page: int Query(1, title頁(yè)碼, description頁(yè)碼, ge1), page_size: int Query(10, title每頁(yè)數(shù)量, description每頁(yè)數(shù)量, ge10, le50), enterprise_name: str Query(None, title企業(yè)名稱, description企業(yè)名稱), submit_time_start: str Query(None, title提交時(shí)間開始, description提交時(shí)間開始), submit_time_end: str Query(None, title提交時(shí)間結(jié)束, description提交時(shí)間結(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就是一個(gè)帶篩選的分頁(yè)查詢。分頁(yè)參數(shù)page/page_size走Query還加了邊界page最小 1page_size卡在 10~50 之間——這等于硬性規(guī)定每頁(yè)至少 10 條、最多 50 條前端想一次拉 100 條是拉不到的。enterprise_name和起止時(shí)間都是可選篩選條件None表示不篩。路由本身不碰數(shù)據(jù)庫(kù)把參數(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 }先把查詢條件動(dòng)態(tài)拼上去有企業(yè)名就按contains模糊匹配填了起止時(shí)間就按submit_time區(qū)間過濾。剩下的交給count算出總數(shù)再用math.ceil算總頁(yè)數(shù)total_count / page_size向上取整避免出現(xiàn)半頁(yè)算不出的情況。分頁(yè)用的是offset((page-1)*page_size).limit(page_size)——也就是跳過前面幾頁(yè)只取當(dāng)前頁(yè)那幾條。真正的重頭戲在for循環(huán)里每家企業(yè)要把它的工商信息、資質(zhì)、審核記錄三張表都撈出來拼一起行業(yè)名稱從industry關(guān)聯(lián)里取取不到就填None。最后返回的不只是列表還把總數(shù)、總頁(yè)數(shù)、當(dāng)前頁(yè)碼、每頁(yè)大小都帶回去前端做分頁(yè)條直接用。管理者端-企業(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è)主體找不到直接報(bào)錯(cuò)。然后一次性把工商信息順帶把industry關(guān)聯(lián)預(yù)加載出來省得后面再查一次、資質(zhì)、審核記錄都查出來拼成同一個(gè)結(jié)構(gòu)返回。跟列表不一樣的地方這里工商信息用的是EnterpriseInfo.get(...)不是get_or_none意味著它默認(rèn)這家企業(yè)一定有對(duì)應(yīng)的工商信息末尾enterpriseinfo.industry.name也是直接取沒做空判斷。所以這段代碼隱含一個(gè)前提——能進(jìn)審核流程的企業(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é)果、理由、備注和審核時(shí)間已經(jīng)有了就走更新分支——注意那個(gè)新值 if 新值 else 舊值的寫法意思是前端沒傳空值的字段就不覆蓋庫(kù)里原來的值只改傳了的。不管新建還是更新審核時(shí)間都刷新成當(dāng)下。最后if review_result 1是關(guān)鍵聯(lián)動(dòng)審核通過1才把企業(yè)的account_status置為NORMAL正常企業(yè)這下才能真正登錄使用。審核不通過review_result不是 1就不動(dòng)賬號(hào)狀態(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(手機(jī)號(hào)不存在) 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(驗(yàn)證碼已過期) if redis_code ! loginMobileRequest.code: raise Exception(驗(yàn)證碼錯(cuò)誤) 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(登錄失敗)先用手機(jī)號(hào)去EnterpriseQualification表里找對(duì)應(yīng)的企業(yè)資質(zhì)記錄。手機(jī)號(hào)沒匹配到時(shí)for循環(huán)一次都不執(zhí)行最后落到raise Exception(登錄失敗)。接著for循環(huán)一個(gè)手機(jī)號(hào)理論上可能關(guān)聯(lián)多個(gè)企業(yè)代碼留了這個(gè)口子所以逐個(gè)看。只有當(dāng)這家企業(yè)審核通過了review_result 1才讓它登錄。登錄時(shí)去 Redis 按手機(jī)號(hào)取之前發(fā)的短信驗(yàn)證碼取不到說明過期了對(duì)不上說明輸錯(cuò)了。都過了才發(fā)access_token/refresh_token發(fā)完順手把 Redis 里的驗(yàn)證碼刪掉一次性憑證不能重復(fù)使用。最后要是循環(huán)走完沒一家滿足就拋登錄失敗。

相關(guān)新聞

Tkinter窗口圖標(biāo)設(shè)置全攻略:從原理到打包的完整解決方案

Tkinter窗口圖標(biāo)設(shè)置全攻略:從原理到打包的完整解決方案

1. 項(xiàng)目概述:為什么窗口圖標(biāo)這么重要?做桌面應(yīng)用開發(fā),尤其是用Python的tkinter,很多人覺得把功能做出來就完事了。但一個(gè)應(yīng)用的“面子工程”——比如窗口左上角那個(gè)小小的圖標(biāo),其實(shí)比你想象中重要得多。我見過不少用tk…

2026/7/29 3:56:02 閱讀更多
STM32 GPIO八種工作模式詳解:從點(diǎn)燈到按鍵狀態(tài)機(jī)實(shí)戰(zhàn)

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

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

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

MicroPython模塊1.2.6解析:從核心機(jī)制到硬件驅(qū)動(dòng)實(shí)戰(zhàn)

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

2026/7/29 3:46:02 閱讀更多
注銷登報(bào)哪家可靠?正規(guī)線上辦理注銷登報(bào)流程指南

注銷登報(bào)哪家可靠?正規(guī)線上辦理注銷登報(bào)流程指南

截至2026年7月,河南登報(bào)遺失聲明沒有政府統(tǒng)一定價(jià)。當(dāng)前線上渠道參考價(jià):全國(guó)公開發(fā)行報(bào)紙120—160元/條,市級(jí)以上公開發(fā)行報(bào)紙160—200元/條;超出套餐字?jǐn)?shù)按2—5元/字計(jì)費(fèi)。鄭州、洛陽(yáng)、開封、南陽(yáng)等地的總價(jià),主要受報(bào)…

2026/7/29 16:37:24 閱讀更多
Python+OpenCV實(shí)現(xiàn)樹莓派攝像頭網(wǎng)絡(luò)流共享與遠(yuǎn)程處理

Python+OpenCV實(shí)現(xiàn)樹莓派攝像頭網(wǎng)絡(luò)流共享與遠(yuǎn)程處理

1. 項(xiàng)目緣起:為什么需要跨設(shè)備共享攝像頭數(shù)據(jù)? 最近在折騰一個(gè)智能家居的監(jiān)控項(xiàng)目,遇到了一個(gè)挺典型的場(chǎng)景:我的主力開發(fā)機(jī)是一臺(tái)性能不錯(cuò)的PC,但攝像頭卻裝在了角落的樹莓派上。我需要用PC上的OpenCV程序來處理樹莓派…

2026/7/29 16:37:24 閱讀更多
Raft 實(shí)現(xiàn)庫(kù)橫向評(píng)測(cè):tikv/raft-rs、openraft 與 actix-raft 的正確性與性能

Raft 實(shí)現(xiàn)庫(kù)橫向評(píng)測(cè):tikv/raft-rs、openraft 與 actix-raft 的正確性與性能

Raft 實(shí)現(xiàn)庫(kù)橫向評(píng)測(cè):tikv/raft-rs、openraft 與 actix-raft 的正確性與性能 一、Raft 實(shí)現(xiàn)庫(kù)的選型困境 Rust 生態(tài)中有三個(gè)主流 Raft 實(shí)現(xiàn)庫(kù):tikv/raft-rs(TiKV 的生產(chǎn)級(jí)實(shí)現(xiàn))、openraft(獨(dú)立 Raft 庫(kù),關(guān)注…

2026/7/29 16:37:24 閱讀更多
【單片機(jī)課設(shè)畢設(shè)項(xiàng)目】基于 STM32 的流量聲光報(bào)警與繼電器控制系統(tǒng)實(shí)現(xiàn),基于嵌入式硬件的多模式流量監(jiān)測(cè)控制器設(shè)計(jì)(010401)

【單片機(jī)課設(shè)畢設(shè)項(xiàng)目】基于 STM32 的流量聲光報(bào)警與繼電器控制系統(tǒng)實(shí)現(xiàn),基于嵌入式硬件的多模式流量監(jiān)測(cè)控制器設(shè)計(jì)(010401)

博主介紹:??碼農(nóng)一枚 ,專注于大學(xué)生項(xiàng)目實(shí)戰(zhàn)開發(fā)、講解和畢業(yè)🚢文撰寫修改等。全棧領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,博客之星、掘金/華為云/阿里云/InfoQ等平臺(tái)優(yōu)質(zhì)作者、專注于Java、小程序技術(shù)領(lǐng)域和畢業(yè)項(xiàng)目實(shí)戰(zhàn) ??技術(shù)范圍:&am…

2026/7/29 16:37:24 閱讀更多
企業(yè)架構(gòu)管理軟件和畫架構(gòu)圖工具有什么區(qū)別?

企業(yè)架構(gòu)管理軟件和畫架構(gòu)圖工具有什么區(qū)別?

畫架構(gòu)圖工具解決“這張圖怎么畫”,企業(yè)架構(gòu)管理軟件解決“對(duì)象、關(guān)系和治理過程怎么長(zhǎng)期維護(hù)”。一次方案討論用 Visio、ProcessOn 或?qū)I(yè)建模工具通常夠用;當(dāng)同一對(duì)象要跨視圖復(fù)用,多部門共同維護(hù),系統(tǒng)變更還要做影響分析和評(píng)審…

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

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

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

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

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

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

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