如何讓我們的網(wǎng)站新聞被百度新聞收錄昨晚廣州天河發(fā)生事件
鶴壁市浩天電氣有限公司
2026/01/24 14:27:26
如何讓我們的網(wǎng)站新聞被百度新聞收錄,昨晚廣州天河發(fā)生事件,wordpress除了博客外主題,網(wǎng)站開發(fā)調(diào)查問卷題在這個(gè) AI 爆發(fā)的時(shí)代#xff0c;如何快速將一個(gè)創(chuàng)意轉(zhuǎn)化為可落地的應(yīng)用#xff1f;本文將帶你通過字節(jié)跳動(dòng)旗下的 AI 開發(fā)平臺(tái) Coze (扣子) 和前端框架 Vue3#xff0c;一步步實(shí)現(xiàn)一個(gè)有趣的“冰球?qū)櫸飻M人化”項(xiàng)目。即使你是零基礎(chǔ)的小白#xff0c;跟著這篇文章也能獨(dú)立…在這個(gè) AI 爆發(fā)的時(shí)代如何快速將一個(gè)創(chuàng)意轉(zhuǎn)化為可落地的應(yīng)用本文將帶你通過字節(jié)跳動(dòng)旗下的 AI 開發(fā)平臺(tái)Coze (扣子)和前端框架Vue3一步步實(shí)現(xiàn)一個(gè)有趣的“冰球?qū)櫸飻M人化”項(xiàng)目。即使你是零基礎(chǔ)的小白跟著這篇文章也能獨(dú)立完成你的第一個(gè) AI 應(yīng)用。一、 項(xiàng)目背景讓寵物變身冰球明星本項(xiàng)目源于一個(gè)節(jié)日活動(dòng)場(chǎng)景用戶只需上傳一張寵物的照片選擇心儀的隊(duì)服編號(hào)、顏色、比賽位置和藝術(shù)風(fēng)格系統(tǒng)就會(huì)通過Coze AI 工作流生成一張?jiān)搶櫸铩皵M人化”后的冰球運(yùn)動(dòng)員海報(bào)。核心技術(shù)棧Coze (扣子)負(fù)責(zé)構(gòu)建 AI 圖片編輯工作流處理邏輯判斷與圖像生成。Vue3 (Composition API)負(fù)責(zé)前端界面搭建收集用戶輸入并展示結(jié)果。Coze API連接前端與 AI 后端實(shí)現(xiàn)數(shù)據(jù)傳輸。二、 后端核心在 Coze 上搭建 AI 工作流Coze 的工作流Workflow就像一個(gè)“加工廠”你只需要把節(jié)點(diǎn)Node像積木一樣連接起來就能實(shí)現(xiàn)復(fù)雜的邏輯。1. 工作流架構(gòu)解析根據(jù)你提供的截圖我們的工作流由以下節(jié)點(diǎn)組成開始節(jié)點(diǎn) (Start)定義輸入?yún)?shù)包括picture用戶上傳的圖片、style風(fēng)格、uniform_number編號(hào)等。代碼節(jié)點(diǎn) (Code)這是提升嚴(yán)謹(jǐn)性的關(guān)鍵。由于用戶輸入的可能是數(shù)字如位置 0 代表守門員代碼節(jié)點(diǎn)負(fù)責(zé)將這些原始數(shù)據(jù)轉(zhuǎn)化為 AI 能聽懂的自然語言描述。imgUnderstand (圖片理解)分析用戶上傳的寵物圖片提取出寵物的品種、毛色、特征。特征提取 (LLM)結(jié)合圖片描述和用戶選定的參數(shù)生成一段詳細(xì)的繪圖提示詞Prompt。圖像生成 (Image Generation)調(diào)用模型根據(jù)提示詞生成最終的冰球運(yùn)動(dòng)員照片。結(jié)束節(jié)點(diǎn) (End)將生成的圖片 URL 返回給前端。2. 代碼節(jié)點(diǎn)的邏輯 (1.ts)在工作流中我們寫了一段簡(jiǎn)單的 TypeScript 代碼來處理數(shù)據(jù)映射const position params.position 0 ? 守門員: (params.position 1 ? 前鋒: 后衛(wèi)); const shooting_hand params.shooting_hand 0 ? 左手: 右手;這段代碼的作用是如果用戶在前端選了“0”它會(huì)自動(dòng)變成“守門員”字樣傳給 AI大大提高了生成圖片的準(zhǔn)確度。三、 前端實(shí)戰(zhàn)Vue3 業(yè)務(wù)邏輯詳解前端部分是我們與用戶交互的窗口。我們將深入講解App.vue中的每一行核心邏輯。1. 響應(yīng)式狀態(tài)管理在 Vue3 中我們使用ref來定義需要隨用戶操作而改變的數(shù)據(jù)const uniform_number ref(10); // 隊(duì)服編號(hào)默認(rèn)10 const status ref(); // 狀態(tài)提示上傳中 - 生成中 - 成功 const imgUrl ref(); // AI 生成后的圖片地址 const imgPreview ref(); // 用戶本地上傳后的預(yù)覽圖2. 圖片預(yù)覽本地加載而非上傳為了提升用戶體驗(yàn)用戶選完圖片應(yīng)立即看到預(yù)覽而不是等上傳成功。const updateImageData () { const input uploadImage.value; // 獲取 DOM 元素 const file input.files[0]; // 獲取選中的文件對(duì)象 const reader new FileReader(); // HTML5 文件讀取器 reader.readAsDataURL(file); // 將圖片轉(zhuǎn)為 Base64 編碼字符串 reader.onload (e) { imgPreview.value e.target.result; // 將 Base64 賦給預(yù)覽圖標(biāo)簽 } }核心邏輯利用FileReader在瀏覽器本地完成讀取不消耗網(wǎng)絡(luò)流量響應(yīng)極快。3. 調(diào)用 Coze API兩步走戰(zhàn)略由于 Coze 的工作流不能直接接收原始文件流我們需要先將文件上傳到 Coze 服務(wù)器換取file_id。第一步上傳文件const uploadFile async () { const formData new FormData(); // 準(zhǔn)備表單數(shù)據(jù) formData.append(file, uploadImage.value.files[0]); const res await fetch(uploadUrl, { method: POST, headers: { Authorization: Bearer ${patToken} }, // 使用個(gè)人訪問令牌鑒權(quán) body: formData }); const ret await res.json(); return ret.data.id; // 返回 file_id };第二步運(yùn)行工作流拿到file_id后連同用戶選擇的樣式、位置等參數(shù)一起發(fā)給工作流const generate async () { status.value 圖片上傳中...; const file_id await uploadFile(); // 先拿 ID status.value 正在生成...; const parameters { picture: JSON.stringify({ file_id: file_id }), // 傳入圖片 ID style: style.value, position: position.value, // ...其他參數(shù) } const res await fetch(workflowUrl, { method: POST, headers: { Authorization: Bearer ${patToken}, Content-Type: application/json }, body: JSON.stringify({ workflow_id, parameters }) // 指定工作流 ID 運(yùn)行 }); const ret await res.json(); const data JSON.parse(ret.data); // 解析返回的 JSON 結(jié)果 imgUrl.value data.data; // 這里的 data.data 是最終生成的圖片 URL };四、 關(guān)鍵點(diǎn)與避坑指南權(quán)限與 Token必須在 Coze 個(gè)人設(shè)置中申請(qǐng)PAT_TOKEN個(gè)人訪問令牌并確保該 Token 有權(quán)限調(diào)用你創(chuàng)建的工作流。安全建議代碼中的patToken不應(yīng)直接寫在前端正式項(xiàng)目中應(yīng)通過后端轉(zhuǎn)發(fā)防止 Token 泄露。Vite 環(huán)境變量在 Vue 項(xiàng)目中敏感信息如 Token建議放在.env.local文件中通過import.meta.env.VITE_xxx調(diào)用。五、拓展Vue3小細(xì)節(jié)1. Vue3 數(shù)據(jù)處理v-model VS ref在App.vue中處理用戶輸入主要有兩種手段v-model雙向綁定適用場(chǎng)景隊(duì)服號(hào)碼uniform_number、顏色選擇uniform_color等普通表單。原理它建立了 HTML 表單元素與 JavaScript 變量之間的“實(shí)時(shí)同步”。當(dāng)你在頁面輸入數(shù)字JS 里的變量會(huì)自動(dòng)更新如果你在 JS 里修改了變量頁面上的顯示也會(huì)隨之改變。refDOM 引用適用場(chǎng)景文件上傳框input typefile。原理瀏覽器出于安全考慮禁止 JavaScript 腳本直接設(shè)置或修改文件上傳框的value。因此v-model在這里無法實(shí)現(xiàn)“寫入”失去了意義。我們必須通過ref直接拿到這個(gè) HTML 元素DOM本身才能讀取到用戶選中的原始文件對(duì)象。2. 屬性與事件綁定:src, change, click這是實(shí)現(xiàn)界面交互的“三劍客”:src屬性綁定在 Vue 中普通的srcxxx只能指向靜態(tài)路徑。加上冒號(hào)的:srcimgUrl表示這是一個(gè)動(dòng)態(tài)變量。當(dāng) AI 生成圖片后JS 將新的地址賦值給imgUrl.valueVue 會(huì)自動(dòng)偵測(cè)到變化并更新頁面圖片。change改變監(jiān)聽用法input typefile changeupdateImageData。作用當(dāng)用戶在文件選擇器中選中了一張圖片這個(gè)事件就會(huì)被觸發(fā)。在項(xiàng)目中我們利用它來立即讀取圖片內(nèi)容并實(shí)現(xiàn)本地預(yù)覽讓用戶在點(diǎn)擊“生成”前就能看到自己上傳的照片。click點(diǎn)擊監(jiān)聽用法button clickgenerate生成/button。作用這是用戶發(fā)起 AI 生成請(qǐng)求的開關(guān)。點(diǎn)擊后程序會(huì)依次執(zhí)行“上傳圖片到服務(wù)器”和“調(diào)用 Coze 工作流”這兩大步驟。3. FormData文件傳輸?shù)募b箱在uploadFile函數(shù)中你會(huì)看到new FormData()的操作。作用在進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí)普通的 JSON 格式文本流無法承載二進(jìn)制的文件數(shù)據(jù)圖片。形象理解FormData 就像一個(gè)特殊的快遞盒專門用來封裝文件以便通過 fetch 安全地發(fā)送到服務(wù)器。六、 總結(jié)通過“Coze 工作流 代碼節(jié)點(diǎn)處理 Vue3 異步請(qǐng)求”我們成功把復(fù)雜的 AI 繪圖邏輯封裝成了一個(gè)簡(jiǎn)單的網(wǎng)頁應(yīng)用。這種“低代碼 AI 后端 靈活前端”的模式是目前快速開發(fā) AI 應(yīng)用的主流選擇。七、App.vue 源碼templatedivclasscontainer!--左側(cè)輸入?yún)^(qū)域--divclassinput!--文件上傳區(qū)域--divclassfile-input!--refuploadImage給這個(gè) input 元素起個(gè)名字方便JS操作它 acceptimage/*只允許選擇圖片文件 required表單提交時(shí)必須選文件但這里我們手動(dòng)處理所以主要是語義 changeupdateImageData當(dāng)用戶選擇了文件就調(diào)用 updateImageData 函數(shù)--input typefilerefuploadImageacceptimage/*required changeupdateImageData//div!--圖片預(yù)覽只有 imgPreview 有值時(shí)才顯示--img:srcimgPreviewalt預(yù)覽圖片v-ifimgPreview/!--表單設(shè)置區(qū)域--divclasssettings!--隊(duì)服編號(hào)--divclassselectionlabel隊(duì)服編號(hào):/label!--v-model 雙向綁定輸入框內(nèi)容 ? uniform_number 變量--input typenumberv-modeluniform_number//div!--隊(duì)服顏色--divclassselectionlabel隊(duì)服顏色:/labelselect v-modeluniform_coloroption value紅紅色/optionoption value綠綠色/optionoption value藍(lán)藍(lán)色/optionoption value白白色/optionoption value黑黑色/option/select/div!--位置--divclassselectionlabel位置:/label!--注意value 是數(shù)字但HTML中寫成字符串也沒問題Vue 會(huì)自動(dòng)轉(zhuǎn)--select v-modelpositionoption:value0前鋒/optionoption:value1后衛(wèi)/optionoption:value2守門員/option/select/div!--持桿手--divclassselectionlabel持桿/labelselect v-modelshooting_handoption value0左手/optionoption value1右手/option/select/div!--風(fēng)格--divclassselectionlabel風(fēng)格/labelselect v-modelstyleoption value寫實(shí)寫實(shí)/optionoption value樂高樂高/optionoption value國(guó)漫國(guó)漫/optionoption value日漫日漫/optionoption value油畫油畫/optionoption value涂鴉涂鴉/optionoption value素描素描/option/select/div/div!--生成按鈕--divclassgeneratebutton clickgenerate生成/button/div/div!--右側(cè)輸出區(qū)域--divclassoutputdivclassgenerated!--顯示AI生成的圖片--img:srcimgUrlaltAI生成圖片v-ifimgUrl/!--顯示狀態(tài)信息如“上傳中...”--div v-ifstatus{{status}}/div/div/div/div/templatescript setup// 引入 Vue 3 的組合式 APIimport{ref,onMounted}fromvue// // 響應(yīng)式數(shù)據(jù)定義相當(dāng)于 Vue 2 的 data// // 表單數(shù)據(jù)用 ref 包裹變成響應(yīng)式constuniform_numberref(10)// 默認(rèn)編號(hào) 10constuniform_colorref(紅)// 默認(rèn)紅色constpositionref(0)// 0前鋒, 1后衛(wèi), 2守門員constshooting_handref(0)// 0左手, 1右手注意這里保持字符串和 option 一致conststyleref(寫實(shí))// 默認(rèn)風(fēng)格// 狀態(tài)管理conststatusref()// 當(dāng)前操作狀態(tài)提示空 / 上傳中 / 生成中...constimgUrlref()// AI 生成的圖片 URL// DOM 引用用于操作文件輸入框constuploadImageref(null)// 初始為 null掛載后指向 input 元素constimgPreviewref()// 本地預(yù)覽圖的 Base64 URL// // ?? 環(huán)境變量 接口配置// constpatTokenimport.meta.env.VITE_PAT_TOKEN;// 從 .env 文件讀取令牌constuploadUrlhttps://api.coze.cn/v1/files/upload;constworkflowUrlhttps://api.coze.cn/v1/workflow/run;constworkflow_id7584046122328555530;// 你的 Workflow ID// // 上傳文件到 Coze 服務(wù)器// constuploadFileasync(){constinputuploadImage.value;// 檢查是否選擇了文件if(!input?.files||input.files.length0){alert(請(qǐng)先選擇一張圖片);returnnull;}// 創(chuàng)建 FormData 對(duì)象用于上傳文件constformDatanewFormData();formData.append(file,input.files[0]);// 把第一個(gè)文件加進(jìn)去try{// 發(fā)送 POST 請(qǐng)求上傳文件constresawaitfetch(uploadUrl,{method:POST,headers:{Authorization:Bearer${patToken}// 攜帶認(rèn)證令牌},body:formData});constretawaitres.json();console.log(上傳響應(yīng):,ret);// 檢查是否上傳成功Coze 返回 code0 表示成功if(ret.code!0){status.value上傳失敗:${ret.msg};returnnull;}// 返回文件 ID用于后續(xù) Workflow 調(diào)用returnret.data.id;}catch(error){status.value網(wǎng)絡(luò)錯(cuò)誤請(qǐng)檢查網(wǎng)絡(luò)或 PAT 令牌;console.error(上傳出錯(cuò):,error);returnnull;}};// // 調(diào)用 AI Workflow 生成圖片// constgenerateasync(){// 重置狀態(tài)imgUrl.value;status.value圖片上傳中...;// 第一步上傳圖片獲取 file_idconstfile_idawaituploadFile();if(!file_id)return;status.value圖片上傳成功正在生成...;// 第二步準(zhǔn)備參數(shù)調(diào)用 Workflowconstparameters{// ?? 注意Coze 的 picture 參數(shù)要求是 JSON 字符串picture:JSON.stringify({file_id:file_id}),style:style.value,uniform_color:uniform_color.value,uniform_number:uniform_number.value,position:position.value,shooting_hand:shooting_hand.value,};try{constresawaitfetch(workflowUrl,{method:POST,headers:{Authorization:Bearer${patToken},Content-Type:application/json// 發(fā)送 JSON 數(shù)據(jù)},body:JSON.stringify({workflow_id,parameters})});constretawaitres.json();console.log(Workflow 響應(yīng):,ret);if(ret.code!0){status.value生成失敗:${ret.msg};return;}// Coze 返回的是字符串化的 JSON需要再解析一次constdataJSON.parse(ret.data);imgUrl.valuedata.data;// 獲取生成的圖片 URLstatus.value;// 清空狀態(tài)}catch(error){status.value生成請(qǐng)求失敗請(qǐng)重試;console.error(生成出錯(cuò):,error);}};// // ? 圖片預(yù)覽功能// constupdateImageData(){constinputuploadImage.value;if(!input?.files||input.files.length0)return;constfileinput.files[0];console.log(選中的文件:,file);// 使用 FileReader 讀取文件為 Base64constreadernewFileReader();reader.readAsDataURL(file);// 異步讀取// 讀取完成后觸發(fā)reader.onload(e){imgPreview.valuee.target.result;// 賦值給預(yù)覽變量};};/scriptstyle scoped.container{display:flex;flex-direction:row;align-items:start;justify-content:start;height:100vh;font-size:0.85rem;}.input{display:flex;flex-direction:column;min-width:330px;padding:20px;}.file-input{margin-bottom:16px;}.settings{display:flex;flex-direction:column;gap:12px;margin-top:1rem;}.selection{display:flex;align-items:center;gap:8px;}.selection input,.selection select{padding:4px;}.generate{margin-top:20px;}button{padding:10px20px;border:1px solid #333;background:#f5f5f5;cursor:pointer;}.output{padding:20px;width:100%;}.generated{width:400px;height:400px;border:1px solid #ccc;display:flex;justify-content:center;align-items:center;background:#fafafa;}.generated img{max-width:100%;max-height:100%;}/style