|
|
@@ -105,49 +105,61 @@
|
|
|
:max-date="maxDate"/>
|
|
|
</van-popup>
|
|
|
<!-- 执行人 -->
|
|
|
- <div style="border: 0.5px solid #87c3ff;margin:0.2rem;position:relative" v-for="item,index in taskform.executorList" :key="index">
|
|
|
- <van-field v-model="item.executorName" :label="'执行人' + (index + 1)" placeholder="请选择执行人" @click="executorChange(item,index)" readonly clickable>
|
|
|
- <template #input>
|
|
|
- <span v-if="!item.executorName"></span>
|
|
|
- <span v-else-if="user.userNameNeedTranslate != 1">{{item.executorName}}</span>
|
|
|
- <span v-else><TranslationOpenDataText type='userName' :openid='item.executorName'></TranslationOpenDataText></span>
|
|
|
- </template>
|
|
|
- </van-field>
|
|
|
+ <div class="executor-table">
|
|
|
+ <table class="executor-table-content">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>执行人</th>
|
|
|
+ <th>计划工时(h)</th>
|
|
|
+ <th v-if="canEdit">操作</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="item,index in taskform.executorList" :key="index">
|
|
|
+ <td @click="canEdit && executorChange(item,index)" class="executor-name-cell">
|
|
|
+ <span v-if="!item.executorName" class="placeholder-text">请选择</span>
|
|
|
+ <span v-else-if="user.userNameNeedTranslate != 1">{{item.executorName}}</span>
|
|
|
+ <span v-else><TranslationOpenDataText type='userName' :openid='item.executorName'></TranslationOpenDataText></span>
|
|
|
+ </td>
|
|
|
+ <td class="plan-hours-cell">
|
|
|
+ <van-stepper v-model="item.planHours" :disabled="!canEdit" :min="0" :max="999"/>
|
|
|
+ </td>
|
|
|
+ <td v-if="canEdit" class="action-cell">
|
|
|
+ <van-icon v-if="index != 0" name="delete-o" @click.stop="deleteExecutor(index)" color="#ee0a24" size="20"/>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
|
|
|
- <van-field label="计划工时">
|
|
|
- <template #input>
|
|
|
- <van-stepper v-model="item.planHours" :disabled="!canEdit"/><span>{{'\u3000h'}}</span>
|
|
|
+ <!-- 项目服务和审核人信息(如果需要) -->
|
|
|
+ <div v-for="item,index in taskform.executorList" :key="'extra-' + index"
|
|
|
+ v-if="(user.companyId == '3092' && item.executorId) || (user.timeType.taskFileCharge == 2 && item.executorId)"
|
|
|
+ class="executor-extra-info">
|
|
|
+ <van-cell-group v-if="user.companyId == '3092' && item.executorId">
|
|
|
+ <van-cell title="项目服务" :value="`${item.serviceName || ''} - ${item.serviceCode || ''}`" is-link @click="searchServiceCli(item,index)">
|
|
|
+ <template #right-icon>
|
|
|
+ <div class="iconBox"></div>
|
|
|
+ </template>
|
|
|
+ </van-cell>
|
|
|
+ </van-cell-group>
|
|
|
+
|
|
|
+ <template v-if="user.timeType.taskFileCharge == 2 && item.executorId">
|
|
|
+ <van-field v-model="item.fileChargeOneName" :label="'审核人1'" placeholder="请选择" @click="executorChange(item,index, 'fileChargeOneName')" readonly clickable>
|
|
|
+ <template #input>
|
|
|
+ <span v-if="!item.fileChargeOneName"></span>
|
|
|
+ <span v-else-if="user.userNameNeedTranslate != 1">{{item.fileChargeOneName}}</span>
|
|
|
+ <span v-else><TranslationOpenDataText type='userName' :openid='item.fileChargeOneName'></TranslationOpenDataText></span>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ <van-field v-model="item.fileChargeTwoName" :label="'审核人2'" placeholder="请选择" @click="executorChange(item,index, 'fileChargeTwoName')" readonly clickable>
|
|
|
+ <template #input>
|
|
|
+ <span v-if="!item.fileChargeTwoName"></span>
|
|
|
+ <span v-else-if="user.userNameNeedTranslate != 1">{{item.fileChargeTwoName}}</span>
|
|
|
+ <span v-else><TranslationOpenDataText type='userName' :openid='item.fileChargeTwoName'></TranslationOpenDataText></span>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
</template>
|
|
|
- </van-field>
|
|
|
- <van-icon v-if="index != 0 && canEdit" class="delete_executor" name="delete-o" @click.stop="deleteExecutor(index)" />
|
|
|
-
|
|
|
- <van-cell-group v-if="user.companyId == '3092'">
|
|
|
- <van-cell title="项目服务" :value="`${item.serviceName || ''} - ${item.serviceCode || ''}`" is-link @click="searchServiceCli(item,index)">
|
|
|
- <template #right-icon>
|
|
|
- <div class="iconBox">
|
|
|
- <!-- <van-icon name="close" size="18" class="iconRight" /> -->
|
|
|
- <!-- <van-icon name="arrow" size="18" class="iconRight" /> -->
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </van-cell>
|
|
|
- </van-cell-group>
|
|
|
-
|
|
|
- <template v-if="user.timeType.taskFileCharge == 2">
|
|
|
- <van-field v-model="item.fileChargeOneName" :label="'审核人1'" placeholder="请选择" @click="executorChange(item,index, 'fileChargeOneName')" readonly clickable>
|
|
|
- <template #input>
|
|
|
- <span v-if="!item.fileChargeOneName"></span>
|
|
|
- <span v-else-if="user.userNameNeedTranslate != 1">{{item.fileChargeOneName}}</span>
|
|
|
- <span v-else><TranslationOpenDataText type='userName' :openid='item.fileChargeOneName'></TranslationOpenDataText></span>
|
|
|
- </template>
|
|
|
- </van-field>
|
|
|
- <van-field v-model="item.fileChargeTwoName" :label="'审核人2'" placeholder="请选择" @click="executorChange(item,index, 'fileChargeTwoName')" readonly clickable>
|
|
|
- <template #input>
|
|
|
- <span v-if="!item.fileChargeTwoName"></span>
|
|
|
- <span v-else-if="user.userNameNeedTranslate != 1">{{item.fileChargeTwoName}}</span>
|
|
|
- <span v-else><TranslationOpenDataText type='userName' :openid='item.fileChargeTwoName'></TranslationOpenDataText></span>
|
|
|
- </template>
|
|
|
- </van-field>
|
|
|
- </template>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 选择项目服务 -->
|
|
|
@@ -180,13 +192,22 @@
|
|
|
</div>
|
|
|
|
|
|
<div class="popupCon conBorder">
|
|
|
- <van-radio-group v-model="executor.item" class="popupItem marginNone borderNone">
|
|
|
+ <!-- 单选模式:用于切换人员 -->
|
|
|
+ <van-radio-group v-if="!executor.isMultiSelect" v-model="executor.item" class="popupItem marginNone borderNone">
|
|
|
<van-radio v-for="uitem in executor.searchList" :key="uitem.id" :name="uitem" style="padding:10px">
|
|
|
<span v-if="user.userNameNeedTranslate != 1" class="userNameClass_left">{{uitem.name}}</span>
|
|
|
<span v-else class="userNameClass_left"><TranslationOpenDataText type='userName' :openid='uitem.name'></TranslationOpenDataText></span>
|
|
|
<span class="userNameClass_right">{{ uitem.jobNumber }}</span>
|
|
|
</van-radio>
|
|
|
</van-radio-group>
|
|
|
+ <!-- 多选模式:用于添加执行人 -->
|
|
|
+ <van-checkbox-group v-if="executor.isMultiSelect" v-model="executor.selectedItems" class="popupItem marginNone borderNone">
|
|
|
+ <van-checkbox v-for="uitem in executor.searchList" :key="uitem.id" :name="uitem" style="padding:10px">
|
|
|
+ <span v-if="user.userNameNeedTranslate != 1" class="userNameClass_left">{{uitem.name}}</span>
|
|
|
+ <span v-else class="userNameClass_left"><TranslationOpenDataText type='userName' :openid='uitem.name'></TranslationOpenDataText></span>
|
|
|
+ <span class="userNameClass_right">{{ uitem.jobNumber }}</span>
|
|
|
+ </van-checkbox>
|
|
|
+ </van-checkbox-group>
|
|
|
</div>
|
|
|
|
|
|
<div class="popupBtn">
|
|
|
@@ -196,7 +217,10 @@
|
|
|
</van-popup>
|
|
|
|
|
|
<!-- 添加执行人 -->
|
|
|
- <div class="add_executor" @click="addExecutor" v-if="canEdit">添加执行人</div>
|
|
|
+ <div class="add_executor" @click="addExecutor" v-if="canEdit">
|
|
|
+ <van-icon name="plus" />
|
|
|
+ <span>添加执行人</span>
|
|
|
+ </div>
|
|
|
<!-- 优先级 -->
|
|
|
<van-field v-model="taskform.taskLevel" label="优先级" @click="taskLevel.show = true" readonly clickable>
|
|
|
<template #input><span>{{taskLevel.list[taskform.taskLevel]}}</span></template>
|
|
|
@@ -274,7 +298,9 @@ export default {
|
|
|
list: [],
|
|
|
searchList: [],
|
|
|
searchText: '',
|
|
|
- type: ''
|
|
|
+ type: '',
|
|
|
+ isMultiSelect: false,
|
|
|
+ selectedItems: []
|
|
|
},
|
|
|
|
|
|
select_project_show: false,
|
|
|
@@ -449,12 +475,13 @@ export default {
|
|
|
this.finishDateShow = false
|
|
|
},
|
|
|
|
|
|
- executorChange(item, index, type){ // 选择执行人
|
|
|
+ executorChange(item, index, type){ // 选择执行人(单选模式)
|
|
|
this.executor.searchText = ''
|
|
|
this.getOnSearch('')
|
|
|
this.executor.show = true
|
|
|
this.executor.index = index
|
|
|
this.executor.type = type
|
|
|
+ this.executor.isMultiSelect = false // 设置为单选模式
|
|
|
this.executor.searchList.forEach(u=>{if (u.id == item.executorId) {
|
|
|
this.executor.item = u
|
|
|
}})
|
|
|
@@ -466,12 +493,12 @@ export default {
|
|
|
},
|
|
|
addExecutor(){
|
|
|
console.log('addExecutor');
|
|
|
- this.taskform.executorList.push({
|
|
|
- executorName: '',
|
|
|
- executorId: '',
|
|
|
- planHours: this.user.timeType.allday
|
|
|
- })
|
|
|
- this.$forceUpdate();
|
|
|
+ // 设置为多选模式并打开弹窗
|
|
|
+ this.executor.searchText = ''
|
|
|
+ this.getOnSearch('')
|
|
|
+ this.executor.isMultiSelect = true
|
|
|
+ this.executor.selectedItems = []
|
|
|
+ this.executor.show = true
|
|
|
},
|
|
|
onSearch(val) {
|
|
|
if(this.user.userNameNeedTranslate != 1) {
|
|
|
@@ -509,22 +536,46 @@ export default {
|
|
|
}).catch(err=> {this.$toast.clear();console.log(err)});
|
|
|
},
|
|
|
searchExecutor(){
|
|
|
- if(!this.executor.type) {
|
|
|
- this.taskform.executorList[this.executor.index].executorId = this.executor.item.id
|
|
|
- this.taskform.executorList[this.executor.index].executorName = this.executor.item.name
|
|
|
- }
|
|
|
-
|
|
|
- if(this.executor.type == 'fileChargeOneName') {
|
|
|
- this.taskform.executorList[this.executor.index].fileChargeOneId = this.executor.item.id
|
|
|
- this.taskform.executorList[this.executor.index].fileChargeOneName = this.executor.item.name
|
|
|
- }
|
|
|
+ // 多选模式:添加执行人
|
|
|
+ if(this.executor.isMultiSelect) {
|
|
|
+ if(this.executor.selectedItems.length === 0) {
|
|
|
+ this.$toast.fail('请至少选择一个执行人');
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 如果第一个执行人是空的,先清除掉
|
|
|
+ if(this.taskform.executorList.length > 0 && !this.taskform.executorList[0].executorId) {
|
|
|
+ this.taskform.executorList.splice(0, 1)
|
|
|
+ }
|
|
|
+ // 将选中的人员添加到执行人列表
|
|
|
+ this.executor.selectedItems.forEach(selectedUser => {
|
|
|
+ this.taskform.executorList.push({
|
|
|
+ executorName: selectedUser.name,
|
|
|
+ executorId: selectedUser.id,
|
|
|
+ planHours: this.user.timeType.allday
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.$forceUpdate();
|
|
|
+ }
|
|
|
+ // 单选模式:切换执行人
|
|
|
+ else {
|
|
|
+ if(!this.executor.type) {
|
|
|
+ this.taskform.executorList[this.executor.index].executorId = this.executor.item.id
|
|
|
+ this.taskform.executorList[this.executor.index].executorName = this.executor.item.name
|
|
|
+ }
|
|
|
+
|
|
|
+ if(this.executor.type == 'fileChargeOneName') {
|
|
|
+ this.taskform.executorList[this.executor.index].fileChargeOneId = this.executor.item.id
|
|
|
+ this.taskform.executorList[this.executor.index].fileChargeOneName = this.executor.item.name
|
|
|
+ }
|
|
|
|
|
|
- if(this.executor.type == 'fileChargeTwoName') {
|
|
|
- this.taskform.executorList[this.executor.index].fileChargeTwoId = this.executor.item.id
|
|
|
- this.taskform.executorList[this.executor.index].fileChargeTwoName = this.executor.item.name
|
|
|
+ if(this.executor.type == 'fileChargeTwoName') {
|
|
|
+ this.taskform.executorList[this.executor.index].fileChargeTwoId = this.executor.item.id
|
|
|
+ this.taskform.executorList[this.executor.index].fileChargeTwoName = this.executor.item.name
|
|
|
+ }
|
|
|
+ console.log('searchExecutor',this.executor.item,this.executor.item.name);
|
|
|
}
|
|
|
+
|
|
|
this.executor.show = false
|
|
|
- console.log('searchExecutor',this.executor.item,this.executor.item.name);
|
|
|
},
|
|
|
|
|
|
taskLevelChange(value,key){ // 优先级
|
|
|
@@ -762,11 +813,31 @@ export default {
|
|
|
margin-top: 46px;
|
|
|
overflow: auto;
|
|
|
.add_executor{
|
|
|
- font-size:13px;
|
|
|
- color:#1989fa;
|
|
|
- padding-left:0.42667rem;
|
|
|
- padding-bottom:.2rem;
|
|
|
- width:100px
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 6px;
|
|
|
+ margin: 12px 16px;
|
|
|
+ padding: 10px 20px;
|
|
|
+ background: #ffffff;
|
|
|
+ color: #1989fa;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ border: 1px solid #1989fa;
|
|
|
+ border-radius: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.98);
|
|
|
+ background: #f7f8fa;
|
|
|
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
|
+ }
|
|
|
+
|
|
|
+ .van-icon {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
}
|
|
|
.delete_executor{
|
|
|
position: absolute;
|
|
|
@@ -776,6 +847,89 @@ export default {
|
|
|
color: #c03131;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// 执行人表格样式
|
|
|
+.executor-table {
|
|
|
+ .executor-table-content {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #ebedf0;
|
|
|
+
|
|
|
+ thead {
|
|
|
+ background: #f7f8fa;
|
|
|
+
|
|
|
+ th {
|
|
|
+ padding: 10px 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #323233;
|
|
|
+ text-align: center;
|
|
|
+ border-bottom: 1px solid #ebedf0;
|
|
|
+
|
|
|
+ &:first-child {
|
|
|
+ text-align: left;
|
|
|
+ padding-left: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tbody {
|
|
|
+ tr {
|
|
|
+ border-bottom: 1px solid #ebedf0;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ td {
|
|
|
+ padding: 10px 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #323233;
|
|
|
+ text-align: center;
|
|
|
+ vertical-align: middle;
|
|
|
+
|
|
|
+ &.executor-name-cell {
|
|
|
+ text-align: left;
|
|
|
+ cursor: pointer;
|
|
|
+ padding-left: 16px;
|
|
|
+
|
|
|
+ .placeholder-text {
|
|
|
+ color: #c8c9cc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.plan-hours-cell {
|
|
|
+ white-space: nowrap;
|
|
|
+ width: 200px;
|
|
|
+
|
|
|
+ .plan-hours-wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 5px;
|
|
|
+
|
|
|
+ .hours-unit {
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.action-cell {
|
|
|
+ width: 60px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .executor-extra-info {
|
|
|
+ margin-top: 0.2rem;
|
|
|
+ border: 1px solid #ebedf0;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+}
|
|
|
.xinmingghao {
|
|
|
overflow: hidden;
|
|
|
text-overflow: ellipsis;
|