@ -103,17 +103,21 @@
< view class = "popup-btns" > < button class = "btn-cancel" @tap ="closeActionPopup" > 取消 < / button > < button class = "btn-danger" : disabled = "actionLoading || !rejectReason.trim()" @tap ="doReject" > 确认驳回 < / button > < / view >
< / template >
< template v-if = "actionPopup.type === 'transfer'" >
< text class = "popup-title" > 完工转交 · 裂变派发 < / text >
< view v-for = "(branch, idx) in transferForm.branches" :key="idx" class="branch-item" >
< view class = "b ranch-header" > < text class= "branch-label" > 分支 { { idx + 1 } } < / text > < text v-if = "transferForm.branches.length > 1" class="b ranch-del" @tap="removeBranch(idx)" > 🗑 ️ 删除 < / text > < / view >
< view class = "form-item" > < text class = "form-label" > 工序 < text class = "required" > * < / text > < / text > < picker mode = "selector" :range = "processOptions" @change ="(e) => onBranchProcessChange(idx, e)" > < view class = "picker-value" > < text : class = "branch.task_name ? '' : 'picker-placeholder'" > { { branch . task _name || '请选择工序' } } < / text > < text class = "picker-arrow" > ▾ < / text > < / view > < / picker > < / view >
< view v-if = "!isBranchWarehouse(idx)" class="form-item"><text class="form-label">接收人 <text class="required">*</text></text><picker mode="selector" :range="userOptions" range-key="name" @change="(e) => onBranchUserChange(idx, e)"><view class="picker-value"><text :class="branchUserName(idx) ? '' : 'picker-placeholder'">{{ branchUserName(idx) || '请选择接收人' }}</text><text class="picker-arrow" > ▾ < / text > < / view > < / picker > < / view >
< view v-if = "isBranchWarehouse(idx)" class="warehouse-hint" > 📦 入库分支 — 直接归档 , 无需指定接收人 < / view >
< / view >
< button class = "btn-add-branch" @tap ="addBranch" > ➕ 添加并行分支 < / button >
< text class = "popup-title" > 完工转交 < / text >
< view class = "form-item" > < text class = "form-label" > 下一道工序 < text class = "required" > * < / text > < / text > < picker mode = "selector" :range = "processOptions" @change ="onTransferProcessChange" > < view class = "picker-value" > < text : class = "transferForm.next_task_name ? '' : 'picker-placeholder'" > { { transferForm . next _task _name || '请选择工序' } } < / text > < text class = "picker-arrow" > ▾ < / text > < / view > < / picker > < / view >
< view v-if = "!t ransferForm.isWarehouse" class="form-item">< text class="form-label">接收人 <text class="required">*</text></text><picker mode="selector" :range="userOptions" range-key="name" @change="onTransferUserChange"><view class="picker-value"><text : class="t ransferUserName ? '' : 'picker-placeholder'">{{ transferUserName || '请选择接收人' }}</text><text class="picker-arrow" > ▾ < / text > < / view > < / picker > < / view >
< view v-if = "transferForm.isWarehouse" class="warehouse-hint" > 📦 入库 — 直接归档 , 无需指定接收人 < / view >
< input v-model = "transferForm.note" class="popup-input" placeholder="交接备注(选填)" style="margin-top:12px;" / >
< view v-if = "transferForm.branches.some(b => b. task_name) " class="preview-hint">将创建 {{ transferForm.branches.length }} 个并行任务:<text v-for="(b, i) in transferForm.branches" :key="i" style="display:block;margin-top:2px;" > {{ i + 1 }} . {{ b. task_name | | ' — ' }} → {{ branchUserName ( i ) | | ( isBranchWarehouse ( i ) ? ' 仓库 ' : ' 未选 ' ) }} < / text > < / view >
< view class = "popup-btns" > < button class = "btn-cancel" @tap ="closeActionPopup" > 取消 < / button > < button class = "btn-primary" : disabled = "actionLoading || !transferForm.branches.some(b => b. task_name) || !canSubmitTransfer " @tap ="doTransfer" > {{ actionLoading ? ' 提交中... ' : ' 确认转交 ( ' + transferForm.branches.length + ' 分支 ) ' }} < / button > < / view >
< view v-if = "transferForm.next_ task_name" class="preview-hint"> {{ transferForm.isWarehouse ? ' 产品将入库并从个人待办中移除 ' : ' 将创建 1 个 「 ' + transferForm.next_ task_name + ' 」 任务指派给 ' + ( transferUserName | | ' — ' ) }} < / view >
< view class = "popup-btns" > < button class = "btn-cancel" @tap ="closeActionPopup" > 取消 < / button > < button class = "btn-primary" : disabled = "actionLoading || !transferForm.next_ task_name || (!transferForm.isWarehouse && !transferForm.selectedUserId) " @tap ="doTransfer" > {{ actionLoading ? ' 提交中... ' : ( transferForm.isWarehouse ? ' 📦 确认入库 ' : ' 确认转交 ' ) }} < / button > < / view >
< / template >
< template v-if = "actionPopup.type === 'spawn'" >
< text class = "popup-title" > ➕ 派发协助分支 < / text >
< text class = "popup-hint" > 为当前任务创建一个并行协助任务 , 当前任务保持进行中 < / text >
< view class = "form-item" > < text class = "form-label" > 工序名称 < text class = "required" > * < / text > < / text > < picker mode = "selector" :range = "spawnProcessOptions" @change ="onSpawnProcessChange" > < view class = "picker-value" > < text : class = "spawnForm.task_name ? '' : 'picker-placeholder'" > { { spawnForm . task _name || '请选择工序' } } < / text > < text class = "picker-arrow" > ▾ < / text > < / view > < / picker > < / view >
< view class = "form-item" > < text class = "form-label" > 接收人 < text class = "required" > * < / text > < / text > < picker mode = "selector" :range = "userOptions" range -key = " name " @change ="onSpawnUserChange" > < view class = "picker-value" > < text : class = "spawnUserName ? '' : 'picker-placeholder'" > { { spawnUserName || '请选择接收人' } } < / text > < text class = "picker-arrow" > ▾ < / text > < / view > < / picker > < / view >
< input v-model = "spawnForm.remark" class="popup-input" placeholder="派发备注(选填)" / >
< view class = "popup-btns" > < button class = "btn-cancel" @tap ="closeActionPopup" > 取消 < / button > < button class = "btn-primary btn-spawn" : disabled = "actionLoading || !spawnForm.task_name || !spawnForm.assignee_id" @tap ="doSpawn" > {{ actionLoading ? ' 提交中... ' : ' 确认派发 ' }} < / button > < / view >
< / template >
< / view >
< / view >
@ -141,13 +145,16 @@ export default {
currentUser : null , currentUserId : "" , currentUsername : "" , currentMode : "tree" ,
processOptions : [ ] , userOptions : [ ] ,
actionPopup : { visible : false , type : "" , task : null } , actionLoading : false , rejectReason : "" , receiveRemark : "" ,
transferForm : { branches : [ { task_name : "" , assignee _id : "" } ] , note : "" } ,
transferForm : { next _ task_name : "" , selectedUserId : "" , isWarehouse : false , note : "" } ,
spawnForm : { task _name : "" , assignee _id : "" , remark : "" } ,
} ;
} ,
computed : {
userLabels ( ) { return this . users . map ( u => ` ${ u . full _name } ( ${ u . username } ) ` ) ; } ,
canDeleteImage ( ) { if ( ! this . recordPopup . task ) return true ; if ( ! this . currentUser ) return true ; return this . currentUser . username === this . recordPopup . task . assignee _id ; } ,
canSubmitTransfer ( ) { return this . transferForm . branche s. every ( b => { if ( ! b . task _name ) return false ; if ( b . task _name === "🏭 入库 (virtual_warehouse)" ) return true ; return ! ! b . assignee _id ; } ) ; } ,
transferUserName ( ) { const u = this . userOption s. find ( u => u . id === this . transferForm . selectedUserId ) ; return u ? u . name : "" ; } ,
spawnUserName ( ) { const u = this . userOptions . find ( u => u . id === this . spawnForm . assignee _id ) ; return u ? u . name : "" ; } ,
spawnProcessOptions ( ) { return ( this . processOptions || [ ] ) . filter ( o => o !== "🏭 入库 (virtual_warehouse)" ) ; } ,
hasMyActiveTask ( ) {
const find = ( tasks ) => { if ( ! tasks ) return false ; for ( const t of tasks ) { if ( ( t . status === 'WIP' || t . status === 'PENDING' ) && ( t . assignee _id == this . currentUserId || t . assignee _id == this . currentUsername ) ) return true ; if ( find ( t . child _tasks ) ) return true ; } return false ; } ;
return this . product ? find ( this . product . task _tree ) : false ;
@ -186,8 +193,10 @@ export default {
if ( type === "record" ) { this . openRecordPopup ( task ) ; return ; }
if ( type === "deleteRecord" ) { this . doDeleteRecord ( record ) ; return ; }
if ( type === "end" ) { this . confirmEndBranch ( task ) ; return ; }
if ( type === "transfer" ) { uni . showLoading ( { title : "加载数据..." } ) ; try { if ( ! this . userOptions . length ) await this . loadUsers ( ) ; if ( ! this . processOptions . length ) this . processOptions = [ "🏭 入库 (virtual_warehouse)" , ... TASK _NAME _OPTIONS ] ; } finally { uni . hideLoading ( ) ; } }
this . actionPopup = { visible : true , type , task } ; this . rejectReason = "" ; this . receiveRemark = "" ; this . transferForm = { branches : [ { task _name : "" , assignee _id : "" } ] , note : "" } ;
if ( type === "transfer" || type === "spawn" ) { uni . showLoading ( { title : "加载数据..." } ) ; try { if ( ! this . userOptions . length ) await this . loadUsers ( ) ; if ( ! this . processOptions . length ) this . processOptions = [ "🏭 入库 (virtual_warehouse)" , ... TASK _NAME _OPTIONS ] ; } finally { uni . hideLoading ( ) ; } }
this . actionPopup = { visible : true , type , task } ; this . rejectReason = "" ; this . receiveRemark = "" ;
this . transferForm = { next _task _name : "" , selectedUserId : "" , isWarehouse : false , note : "" } ;
this . spawnForm = { task _name : "" , assignee _id : "" , remark : "" } ;
} ,
handleViewRecords ( task ) { uni . navigateTo ( { url : ` /pages/scan/records?taskId= ${ task . id } ` } ) ; } ,
async doDeleteRecord ( record ) { try { await request ( { url : ` /records/ ${ record . id } ` , method : "DELETE" } ) ; uni . showToast ( { title : "记录已删除" , icon : "success" } ) ; this . doQuery ( this . product . serial _number ) ; } catch { } } ,
@ -196,13 +205,14 @@ export default {
closeActionPopup ( ) { this . actionPopup = { visible : false , type : "" , task : null } ; } ,
async doReceive ( ) { this . actionLoading = true ; try { const remark = this . receiveRemark . trim ( ) || undefined ; const opId = this . currentUsername || this . currentUserId ; await post ( ` /tasks/ ${ this . actionPopup . task . id } /receive?operator_id= ${ encodeURIComponent ( opId ) } ` , { remark } ) ; uni . showToast ( { title : "已接收" , icon : "success" } ) ; this . closeActionPopup ( ) ; this . doQuery ( this . product . serial _number ) ; } catch { } finally { this . actionLoading = false ; } } ,
async doReject ( ) { this . actionLoading = true ; try { const opId = this . currentUsername || this . currentUserId ; await post ( ` /tasks/ ${ this . actionPopup . task . id } /reject?operator_id= ${ encodeURIComponent ( opId ) } ` , { reason : this . rejectReason . trim ( ) } ) ; uni . showToast ( { title : "已驳回" , icon : "success" } ) ; this . closeActionPopup ( ) ; this . doQuery ( this . product . serial _number ) ; } catch { } finally { this . actionLoading = false ; } } ,
addBranch ( ) { if ( this . transferForm . branches . length >= 5 ) { uni . showToast ( { title : "最多 5 个分支" , icon : "none" } ) ; return ; } this . transferForm . branches . push ( { task _name : "" , assignee _id : "" } ) ; } ,
removeBranch ( idx ) { if ( this. transferForm . branches . length > 1 ) this . transferForm . branches . splice ( idx , 1 ) ; } ,
onB ranchProcess Change ( idx , e) { this . transferForm . branches [ idx ] . task _name = this . process Options[ e . detail . value ] ; this . transferForm . branches [ idx ] . assignee _id = "" ; } ,
onBranchUserChange ( idx , e ) { const user = this . userOptions [ e . detail . value ] ; if ( user ) this . transferForm . branches [ idx ] . assignee _id = user . id ; } ,
isBranchWarehouse ( idx ) { return this . transferForm . branches [ idx ] . task _name === "🏭 入库 (virtual_warehouse)" ; } ,
branchUserNam e( idx ) { const u = this . userOptions . find ( u => u . id === this . transferForm . branches [ idx ] . assignee _id ) ; return u ? u . name : "" ; } ,
async doTransfer ( ) { this . actionLoading = true ; const branches = this . transferForm . branches . filter ( b => b . task _name ) ; try { await post ( ` /tasks/ ${ this . actionPopup . task . id } /transfer ` , { next _tasks : branches . map ( b => ( { task _name : b . task _name , assignees : b . task _name === "🏭 入库 (virtual_warehouse)" ? [ "virtual_warehouse" ] : [ b . assignee _id ] } ) ) , note : this . transfer Form. note . trim ( ) || undefined } ) ; uni . showToast ( { title : "派发成功" , icon : "success" } ) ; this . closeActionPopup ( ) ; this . doQuery ( this . product . serial _number ) ; } catch { } finally { this . actionLoading = false ; } } ,
// 转交(单线)
onTransferProcessChange ( e ) { this . transferForm . next _task _name = this . processOptions [ e . detail . value ] ; this . transferForm . isWarehouse = this . transferForm . next _task _name === "🏭 入库 (virtual_warehouse)" ; this . transferForm . selectedUserId = "" ; } ,
onT ransferUser Change ( e ) { const user = this . user Options[ e . detail . value ] ; if ( user ) this. transferForm . selectedUserId = user . id ; } ,
async doTransfer ( ) { this . actionLoading = true ; try { const assignees = this . transferForm . isWarehouse ? [ "virtual_warehouse" ] : [ this . transferForm . selectedUserId ] ; await post ( ` /tasks/ ${ this . actionPopup . task . id } /transfer ` , { next _tasks : [ { task _name : this . transferForm . next _task _name , assignees } ] , note : this . transferForm . note . trim ( ) || undefined } ) ; uni . showToast ( { title : this . transferForm . isWarehouse ? "已入库" : "转交成功" , icon : "success" } ) ; this . closeActionPopup ( ) ; this . doQuery ( this . product . serial _number ) ; } catch { } finally { this . actionLoading = false ; } } ,
// 派发协助分支
onSpawnProcessChang e( e ) { this . spawnForm . task _name = this . spawnProcessOptions [ e . detail . value ] ; } ,
onSpawnUserChange ( e ) { const user = this . userOptions [ e . detail . value ] ; if ( user ) this . spawn Form. assignee _id = user . id ; } ,
async doSpawn ( ) { this . actionLoading = true ; try { const opId = this . currentUsername || this . currentUserId ; await post ( ` /tasks/ ${ this . actionPopup . task . id } /spawn?operator_id= ${ encodeURIComponent ( opId ) } ` , { task _name : this . spawnForm . task _name , assignee _id : this . spawnForm . assignee _id , remark : this . spawnForm . remark . trim ( ) || undefined } ) ; uni . showToast ( { title : "协助分支已派发" , icon : "success" } ) ; this . closeActionPopup ( ) ; this . doQuery ( this . product . serial _number ) ; } catch { } finally { this . actionLoading = false ; } } ,
} ,
} ;
< / script >