AddTask.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. <template>
  2. <el-dialog :title="title" :visible.sync="visible_" :close-on-click-modal="false" :before-close="close_before" top="5%" append-to-body width="660px">
  3. <div style="max-height: 600px;overflow-y: scroll;" class="scroll-bar">
  4. <el-form label-width="100px" :model="form">
  5. <div class="add-task-title">基本信息</div>
  6. <el-form-item label="任务名称">
  7. <el-input v-model="form.name" maxlength="100" show-word-limit class="w270" type="textarea" autosize placeholder="请输入任务名称"></el-input>
  8. </el-form-item>
  9. <el-form-item label="负责人">
  10. <div class="flex-box-ce cursor" @click="showSelectorUser(1)">
  11. <userImage :id="owner_userInfo.id" fontSize="14" width="36px" height="36px" :user_name="owner_userInfo.name"></userImage>
  12. <span style="margin-left: 10px;font-size: 14px;color: #3F4755;">{{ owner_userInfo.name }}</span>
  13. </div>
  14. </el-form-item>
  15. <el-form-item label="起止时间" style="margin-right: 20px;">
  16. <el-date-picker :picker-options="instantPickerOptions" v-model="form.date" :clearable="false" type="datetimerange" range-separator="至" value-format="yyyy-MM-dd HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['8:00:00', '18:00:00']"></el-date-picker>
  17. </el-form-item>
  18. <el-form-item label="目标值">
  19. <el-input class="w270" placeholder="请输入数值" v-model="form.target" @input="form.target = form.target.replace(/[^\d]/g, '');">
  20. <el-select style="width: 100px;" v-model="form.unit" slot="append" placeholder="请选择">
  21. <el-option v-for="item in unitList" :key="item.name" :label="item.name" :value="item.name"></el-option>
  22. </el-select>
  23. </el-input>
  24. </el-form-item>
  25. <template v-if="isShowGl">
  26. <el-form-item label="母任务">
  27. <div class="cursor" style="border-radius: 4px;border: 1px solid #dcdfe6;line-height: 34px;width: 400px;padding: 0 15px;">
  28. <div class="fontColorC" v-if="!target_plan_id" @click="isShowRelevanceTask=true">请选择所属任务</div>
  29. <div class="showUpdate" v-else ><span class="cursor" @click="isShowRelevanceTask=true">{{motherTaskName}}</span> <i class="el-icon-error cursor" @click="clearRelevanceTask"></i></div>
  30. </div>
  31. </el-form-item>
  32. <el-form-item label="所属KR/项目">
  33. <div class="cursor" style="border-radius: 4px;border: 1px solid #dcdfe6;line-height: 34px;width: 400px;padding: 0 15px;">
  34. <Tooltip preHtml="更改所属KR/项目:请先取消关联母任务" v-if="target_plan_id">
  35. <span class="fontColorC">{{krName||'更改所属KR:请先取消关联母任务'}}</span>
  36. </Tooltip>
  37. <template v-else>
  38. <div class="fontColorC" v-if="!target_id" @click="isShowDateSearch=true">请选择所属KR/项目</div>
  39. <div class="showUpdate" v-else>
  40. <span class="blue">{{selectTarget_type==2? 'KR':selectTarget_type==4? '项目':'里程碑'}}:</span>
  41. <span class="cursor" @click="isShowDateSearch=true">{{krName}}</span>
  42. <i class="el-icon-error cursor" @click="target_id=0"></i>
  43. </div>
  44. </template>
  45. </div>
  46. </el-form-item>
  47. </template>
  48. <div style="text-align: right;">
  49. <span class="blue cursor" v-if="!isShowGd" @click="isShowGd=!isShowGd">更多属性<i class="el-icon-arrow-down"></i></span>
  50. <span class="blue cursor" v-else @click="isShowGd=!isShowGd">收起 <i class="el-icon-arrow-up"></i></span>
  51. </div>
  52. <CollapseTransition>
  53. <!-- 任务要求 -->
  54. <div v-show="isShowGd">
  55. <el-form-item label="可见范围">
  56. <el-select class="w270" v-model="form.visible_type" placeholder="请选择">
  57. <el-option label="全公司" :value="1"></el-option>
  58. <el-option label="指定部门" :value="5"></el-option>
  59. <el-option label="相关成员" :value="2"></el-option>
  60. </el-select>
  61. </el-form-item>
  62. <el-form-item label="部门" prop="dept_ids" v-if="form.visible_type==5">
  63. <div class="w270" style="position: relative;">
  64. <el-input auto-complete="off" v-model="deptVisibleName" placeholder="请选择部门"></el-input>
  65. <div @click="show_dept_selector = true" style=" position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;"></div>
  66. </div>
  67. </el-form-item>
  68. <el-form-item label="进展反馈">
  69. <div class="border flex-box-ce">
  70. <div class="flex-1"></div>
  71. <Feedback @confirm="feedbackTime" style="width: 100%;">
  72. <div class="inputDc" :class="isShowGd?'bj':''">
  73. <span class="fontColorD" v-if="!form.feedbackTime">请选择反馈时间</span><span v-else>{{form.feedbackTime}}</span>
  74. </div>
  75. </Feedback>
  76. <i class="el-icon-arrow-down icon-right" v-if="!form.feedbackTime"></i>
  77. <i class="el-icon-error cursor" v-else @click="form.feedbackTime=''"></i>
  78. </div>
  79. </el-form-item>
  80. <el-form-item label="审批人">
  81. <div class="flex-box-ce cursor" v-if="reviewer_userInfo.id" @click="showSelectorUser(2)">
  82. <userImage :id="reviewer_userInfo.id" fontSize="14" width="36px" height="36px" :user_name="reviewer_userInfo.name"></userImage>
  83. <span style="margin-left: 10px;font-size: 14px;color: #3F4755;">{{ reviewer_userInfo.name }}</span>
  84. </div>
  85. <i class="el-icon-plus cursor" v-else @click="showSelectorUser(2)"></i>
  86. </el-form-item>
  87. <el-form-item label="预估工时">
  88. <el-input class="w270" placeholder="请输入工时" v-model="form.wh" @input="form.wh = form.wh.replace(/[^\d]/g, '');"><div slot="append">小时</div></el-input>
  89. </el-form-item>
  90. <el-form-item label="参与人">
  91. <div class="cursor" style="border-radius: 4px;border: 1px solid #dcdfe6;line-height: 34px;width: 400px;padding: 0 15px;" @click="show_employee_selector_all=true">
  92. <div class="flex-box-ce fontColorB font-flex-word" v-if="employee_selected_all.employee.length>0">
  93. <span v-for="item in employee_selected_all.employee" :key="item.id"> {{item.name}},</span>
  94. </div>
  95. <div v-else style="color: #C0C4CF;">请选择参与人员</div>
  96. </div>
  97. </el-form-item>
  98. <el-form-item label="任务描述">
  99. <el-input v-model="form.content" placeholder="请输入详情" class="w270" maxlength="500" show-word-limit type="textarea" clearable></el-input>
  100. </el-form-item>
  101. <el-form-item label="附件">
  102. <uploadOss :file-list="fileList" :headers="$xtoken" :action="$action" :limit="3" :accept="$acceptImgFile" :multiple="true" :on-success="handleSuccess" :before-upload="beforeFilesUpload">
  103. <span class="fontColorC"><i class="el-icon-paperclip green" style="padding-right: 5px;"></i>请添加附件</span>
  104. </uploadOss>
  105. <div v-if="files.length>0" class="flex-box-ce flex-d-wrap">
  106. <div class="files-box flex-box-ce" v-for="(item,index) in files" :key="index">
  107. <el-image v-if="item.type=='img'" style="width: 30px; height: 30px;cursor: pointer;" :src="item.file" :preview-src-list="[item.file]"></el-image>
  108. <span v-else ><img @click="$onFilePreView(item.file)" style="width: 30px; height: 30px;margin-top: 14px;cursor: pointer;" src="static/images/excel_icon.png"/></span>
  109. <Tooltip :preHtml="item.name">
  110. <div style="margin-left: 10px;width: 120px;">{{item.name}}</div>
  111. </Tooltip>
  112. <Tooltip preHtml="删除">
  113. <i class="el-icon-error cursor" @click="deleteFlie(index)"></i>
  114. </Tooltip>
  115. </div>
  116. </div>
  117. </el-form-item>
  118. </div>
  119. </CollapseTransition >
  120. </el-form>
  121. </div>
  122. <div class="flex-box-ce flex-box-end" style="margin-top: 20px;">
  123. <el-button @click="close">取 消</el-button>
  124. <el-button type="primary" @click="confirm" :disabled="wait">确 定</el-button>
  125. </div>
  126. <!-- 关联任务 -->
  127. <RelevanceTask :visible.sync="isShowRelevanceTask" :id="target_plan_id" @confirm="ActiveRelevanceTask"></RelevanceTask>
  128. <!-- 对齐目标 -->
  129. <TargetSearch :visible.sync="isShowDateSearch" title="所属KR" :showSelectType="3" :showType="2" @confirm="confirmTarget"></TargetSearch>
  130. <!-- 选择负责人 -->
  131. <EmployeeSelector :is_filtration_creator="false" title="选择人员" :isChecKedAll="false" :isRequired="selectUserIndex==1" :multi="false" :selected="employee_selected" :visible.sync="show_employee_selector" @confirm="employee_confirm"/>
  132. <!-- 选择参与人 -->
  133. <EmployeeSelector :is_filtration_creator="false" title="选择人员" :selected="employee_selected_all" :visible.sync="show_employee_selector_all" @confirm="employee_confirm_all"/>
  134. <ShowImg :visible.sync="isShowImg" :imgUrl="imgUrl"></ShowImg>
  135. <EmployeeSelector :isChecKedAll="false" :can_select_employee="false" :can_select_dept="true" :multi="true" :selected="dept_selected" :visible.sync="show_dept_selector"@confirm="dept_confirm"/>
  136. </el-dialog>
  137. </template>
  138. <script>
  139. import EmployeeSelector from '@/components/EmployeeSelector';
  140. import Feedback from '@/okr/components/public/Feedback'; //反馈时间组件
  141. import CollapseTransition from '@/okr/utils/collapse-transition';
  142. import uploadOss from '@/components/upload';
  143. import TargetSearch from '@/okr/components/public/TargetSearch'; //反馈时间组件
  144. import ShowImg from '@/okr/components/public/ShowImg'; //反馈时间组件
  145. import Tooltip from '@/components/Tooltip'; //鼠标悬浮显示文字
  146. import RelevanceTask from '@/okr/components/public/RelevanceTask'; //关联任务
  147. import moment from 'moment' // 时间库
  148. export default {
  149. name: 'AddTask',
  150. components:{EmployeeSelector,CollapseTransition,uploadOss,Feedback,ShowImg,Tooltip,TargetSearch,RelevanceTask},
  151. props: {
  152. title: {
  153. // 标题
  154. type: String,
  155. default: '添加任务'
  156. },
  157. visible: {
  158. // 是否显示组件
  159. type: Boolean,
  160. default: false
  161. },
  162. target_type:{ // 0-不绑定对象 1-目标 2-KR 3-计划(分解计划下的子计划的时候) 4-项目 5-里程碑
  163. type: Number,
  164. default: 2
  165. },
  166. isShowGl:{//是否显示关联
  167. type: Boolean,
  168. default: false
  169. },
  170. id:{ // 绑定的对象id 跟对象种类配对使用
  171. type: Number,
  172. default: 0,
  173. },
  174. initDate:{
  175. type: Array,
  176. default:()=>{
  177. return [];
  178. }
  179. }
  180. },
  181. data() {
  182. return {
  183. wait:false,
  184. owner_userInfo: this.$userInfo(),//负责人
  185. reviewer_userInfo:{},//审批人
  186. isShowGd:false,
  187. visible_:false,
  188. unitList:this.$getCache('unitList'),
  189. files: [], //文件附件
  190. fileList:[],
  191. isShowImg:false,
  192. imgUrl:'',//显示图片Url
  193. form: {
  194. name: '',// 是 计划名
  195. owner_id: this.$userInfo().id,// 是 integer 负责人id
  196. level : '1',// 是 string 优先等级 1-最高 2-高 3-中 4-低 5-非常低
  197. visible_type: 1,//是 string 可见范围种类 1-全公司 2-相关成员 5-指定部门可见
  198. target_type: this.target_type,//是 string 计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
  199. target_id: this.id,//是 integer 绑定的对象id 跟对象种类配对使用
  200. date:[`${this.$moment().format('YYYY-MM-DD')} 00:00:00`,`${this.$moment().format('YYYY-MM-DD')} 23:59:00`],
  201. start_date: `${this.$moment().format('YYYY-MM-DD')} 00:00:00`,//是 string 计划开始日期 格式:2022-01-01
  202. end_date: `${this.$moment().format('YYYY-MM-DD')} 23:59:00`,//是 string 计划结束日期 格式:2022-01-01
  203. content: '',//否 string 计划描述,没有的时候不要上传这个字段,空字符也不行
  204. reviewer_id: '',//否 integer 审批者id,没有的时候不要上传这个字段,空字符也不行
  205. wh: '',//否 string 预估工时,没有填写的时候不要上传这个字段,空字符也不行
  206. dept_ids: '',// 否 string 部门id列表,以逗号分割,只有可见范围种类为指定部门可见才需要上传这个字段,没有的时候不要上传这个字段,空字符也不行
  207. joiner_ids: '',// 否 string 参与者id列表,以逗号分割,没有的时候不要上传这个字段,空字符也不行
  208. files: '',// 否 string 附件列表,以逗号分割,没有的时候不要上传这个字段,空字符也不行
  209. target: '',// 否 integer 量化配置的目标值,只有配置了量化配置的时候需要上传,没有的时候不要上传这个字段,空字符也不行
  210. unit: '元',// 否 string 量化配置的单位值,只有配置了量化配置的时候需要上传,没有的时候不要上传这个字段,空字符也不行
  211. feedbackTime:'',
  212. scope_type: '',// 否 string 反馈配置的时间种类 1-每天 2-每个工作日 3-每周 4-每月 5-今天 6-明天
  213. special_date: '',// 否 string
  214. daily_time: '',// 否 string 当反馈配置的时间种类为每天的时候必须传入,否则不要上传这个字段,空字符也不行. 数据格式:23:30:00
  215. work_day_time: '',// 否 string 当反馈配置的时间种类为每个工作日的时候必须传入,否则不要上传这个字段,空字符也不行. 数据格式:23:30:00
  216. week_day: '',// 否 integer 当反馈配置的时间种类为每周的时候必须传入,否则不要上传这个字段,空字符也不行. 数值在1-7之间 1-周一 2-周二 3-周三 4-周四 5-周五 6-周六 7-周日
  217. week_day_time: '',// 否 string 当反馈配置的时间种类为每周的时候必须传入,否则不要上传这个字段,空字符也不行.数据格式:23:30:00
  218. month_day: '',// 否 string 当反馈配置的时间种类为每月的时候必须传入,否则不要上传这个字段,空字符也不行. 数值在1-31之间,分别代表每月的几号
  219. month_day_time: '',// 否 string 当反馈配置的时间种类为每月的时候必须传入,否则不要上传这个字段,空字符也不行.数据格式:23:30:00
  220. },
  221. employee_selected: { dept: [], employee: [] },
  222. show_employee_selector: false,
  223. employee_selected_all: { dept: [], employee: [] },
  224. show_employee_selector_all: false,
  225. selectUserIndex:1,
  226. // 部门可见
  227. deptVisibleName: null,
  228. dept_selected: {dept: [],employee:[]},
  229. show_dept_selector: false,
  230. instantPickerOptions: {
  231. shortcuts: [
  232. {
  233. text: "今天",
  234. onClick(picker) {
  235. picker.$emit("pick", [`${moment().format('YYYY-MM-DD')} 00:00:00`,`${moment().format('YYYY-MM-DD')} 23:59:00`]);
  236. }
  237. },
  238. {
  239. text: "明天",
  240. onClick(picker) {
  241. picker.$emit("pick", [`${moment().add(1, "days").format('YYYY-MM-DD')} 00:00:00`,`${moment().add(1, "days").format('YYYY-MM-DD')} 23:59:00`]);
  242. }
  243. },
  244. {
  245. text: "本周",
  246. onClick(picker) {
  247. let start_date=moment().week(moment().week()).startOf('isoweek').format('YYYY-MM-DD 00:00:00')
  248. let end_date=moment().week(moment().week()).endOf('isoweek').format('YYYY-MM-DD 23:59:00')
  249. picker.$emit("pick", [start_date, end_date]);
  250. }
  251. },
  252. {
  253. text: "下周",
  254. onClick(picker) {
  255. let start_date=moment().week(moment().week() + 1).startOf('isoweek').format('YYYY-MM-DD 00:00:00')
  256. let end_date=moment().week(moment().week() + 1).endOf('isoweek').format('YYYY-MM-DD 23:59:00')
  257. picker.$emit("pick", [start_date, end_date]);
  258. }
  259. },
  260. {
  261. text: "本月",
  262. onClick(picker) {
  263. let start_date=moment().startOf('month').format('YYYY-MM-DD 00:00:00')
  264. let end_date=moment().endOf('month').format('YYYY-MM-DD 23:59:00')
  265. picker.$emit("pick", [start_date, end_date]);
  266. }
  267. },
  268. {
  269. text: "下个月",
  270. onClick(picker) {
  271. let start_date=moment().add(1, "month").startOf('month').format('YYYY-MM-DD 00:00:00')
  272. let end_date=moment().add(1, "month").endOf('month').format('YYYY-MM-DD 23:59:00')
  273. picker.$emit("pick", [start_date, end_date]);
  274. }
  275. }
  276. ]
  277. },
  278. //关联母任务
  279. isShowRelevanceTask:false,
  280. motherTaskName:'',
  281. target_plan_id:0,
  282. //关联KR
  283. target_id:0,
  284. krName:'',
  285. isShowDateSearch:false,
  286. selectTarget_type:0,//选择的关联的类型
  287. };
  288. },
  289. watch: {
  290. visible(val) {
  291. this.visible_ = JSON.parse(JSON.stringify(val));
  292. if(val){
  293. this.initData();
  294. }
  295. },
  296. 'form.date'(newValue, oldValue) {
  297. if(newValue){
  298. this.form.start_date=newValue[0];
  299. this.form.end_date=newValue[1];
  300. }else{
  301. this.form.start_date='';
  302. this.form.end_date='';
  303. }
  304. },
  305. isShowGd(val){
  306. if(val){
  307. this.form.unit='元'
  308. }
  309. }
  310. },
  311. methods: {
  312. //获取KR的名称
  313. getTaskDateil(id){
  314. this.$axiosUser('get', '/api/pro/okr/plan/info',{plan_id:id}).then(res => {
  315. let data=res.data.data
  316. if(data.kr_id){ //kr
  317. this.krName=data.kr_name;
  318. }else if(data.milestone_id){ //里程碑
  319. this.krName=data.milestone_name;
  320. }else if(data.project_id){ //项目
  321. this.krName=data.project_name;
  322. }
  323. })
  324. },
  325. clearRelevanceTask(){
  326. this.motherTaskName='';
  327. this.target_plan_id=0;
  328. },
  329. //关联母任务
  330. ActiveRelevanceTask(item){
  331. this.getTaskDateil(item.id)
  332. this.motherTaskName=item.name;
  333. this.target_plan_id=item.id;
  334. this.target_id=0;
  335. },
  336. confirmTarget(item){
  337. this.krName=item.item.name;
  338. this.target_id=item.item.id;
  339. this.selectTarget_type=item.type;
  340. },
  341. initData(){
  342. this.isShowGd=false;
  343. this.files= []; //文件附件
  344. this.fileList=[];
  345. this.krName='';
  346. this.target_id=0;
  347. this.selectTarget_type=0;
  348. this.motherTaskName='';
  349. this.target_plan_id=0;
  350. this.isShowImg=false;
  351. this.imgUrl='';//显示图片Url
  352. this.form= {
  353. name: '',// 是 计划名
  354. owner_id: this.$userInfo().id,// 是 integer 负责人id
  355. level : '1',// 是 string 优先等级 1-最高 2-高 3-中 4-低 5-非常低
  356. visible_type: 1,//是 string 可见范围种类 1-全公司 2-相关成员 5-指定部门可见
  357. target_type: this.target_type,//是 string 计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
  358. target_id: this.id,//是 integer 绑定的对象id 跟对象种类配对使用
  359. date:[`${this.$moment().format('YYYY-MM-DD')} 00:00:00`,`${this.$moment().format('YYYY-MM-DD')} 23:59:00`],
  360. start_date: `${this.$moment().format('YYYY-MM-DD')} 00:00:00`,//是 string 计划开始日期 格式:2022-01-01
  361. end_date: `${this.$moment().format('YYYY-MM-DD')} 23:59:00`,//是 string 计划结束日期 格式:2022-01-01
  362. content: '',//否 string 计划描述,没有的时候不要上传这个字段,空字符也不行
  363. reviewer_id: '',//否 integer 审批者id,没有的时候不要上传这个字段,空字符也不行
  364. wh: '',//否 string 预估工时,没有填写的时候不要上传这个字段,空字符也不行
  365. dept_ids: '',// 否 string 部门id列表,以逗号分割,只有可见范围种类为指定部门可见才需要上传这个字段,没有的时候不要上传这个字段,空字符也不行
  366. joiner_ids: '',// 否 string 参与者id列表,以逗号分割,没有的时候不要上传这个字段,空字符也不行
  367. files: '',// 否 string 附件列表,以逗号分割,没有的时候不要上传这个字段,空字符也不行
  368. target: '',// 否 integer 量化配置的目标值,只有配置了量化配置的时候需要上传,没有的时候不要上传这个字段,空字符也不行
  369. unit: '元',// 否 string 量化配置的单位值,只有配置了量化配置的时候需要上传,没有的时候不要上传这个字段,空字符也不行
  370. feedbackTime:'',
  371. scope_type: '',// 否 string 反馈配置的时间种类 1-每天 2-每个工作日 3-每周 4-每月 5-今天 6-明天
  372. special_date: '',// 否 string
  373. daily_time: '',// 否 string 当反馈配置的时间种类为每天的时候必须传入,否则不要上传这个字段,空字符也不行. 数据格式:23:30:00
  374. work_day_time: '',// 否 string 当反馈配置的时间种类为每个工作日的时候必须传入,否则不要上传这个字段,空字符也不行. 数据格式:23:30:00
  375. week_day: '',// 否 integer 当反馈配置的时间种类为每周的时候必须传入,否则不要上传这个字段,空字符也不行. 数值在1-7之间 1-周一 2-周二 3-周三 4-周四 5-周五 6-周六 7-周日
  376. week_day_time: '',// 否 string 当反馈配置的时间种类为每周的时候必须传入,否则不要上传这个字段,空字符也不行.数据格式:23:30:00
  377. month_day: '',// 否 string 当反馈配置的时间种类为每月的时候必须传入,否则不要上传这个字段,空字符也不行. 数值在1-31之间,分别代表每月的几号
  378. month_day_time: '',// 否 string 当反馈配置的时间种类为每月的时候必须传入,否则不要上传这个字段,空字符也不行.数据格式:23:30:00
  379. };
  380. if(this.initDate.length>0){
  381. let initDate=this.initDate;
  382. this.form.date=[`${initDate[0]} 00:00:00`,`${initDate[1]} 23:59:00`];
  383. }
  384. this.owner_userInfo=this.$userInfo();//负责人
  385. this.reviewer_userInfo={};//审批人
  386. this.employee_selected= { dept: [], employee: [] };
  387. this.show_employee_selector= false;
  388. this.employee_selected_all= { dept: [], employee: [] };
  389. this.show_employee_selector_all= false;
  390. this.selectUserIndex=1;
  391. // 部门可见
  392. this.deptVisibleName= null;
  393. this.dept_selected= {dept: [],employee:[]};
  394. this.show_dept_selector= false;
  395. this.$forceUpdate();
  396. },
  397. deleteFlie(index){
  398. this.files.splice(index,1);
  399. this.fileList.splice(index,1);
  400. },
  401. handleSuccess(response, file, fileList) {
  402. this.fileList=fileList;
  403. let files=JSON.parse(JSON.stringify(fileList));
  404. let fileListData=files.map(e=>{
  405. let type=e.name.split('.');
  406. type=type[type.length-1]
  407. let str='';
  408. if(type=='jpeg'||type=='png'||type=='jpg'||type=='JPEG'||type=='PNG'||type=='JPG'){
  409. str='img'
  410. }else{
  411. str='file'
  412. }
  413. let obj={
  414. name:e.name,
  415. file:e.url,
  416. type:str,
  417. }
  418. return obj
  419. })
  420. this.files = fileListData;
  421. },
  422. // 图片上传
  423. beforeUpload(file) {
  424. const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
  425. const isLt2M = file.size / 1024 / 1024 <5;
  426. if (!isJPG) {
  427. this.$message.error('上传图片只能是 jpeg|png|jpg 格式!');
  428. }
  429. if (!isLt2M) {
  430. this.$message.error('上传图片大小不能超过 5MB!');
  431. }
  432. return isJPG && isLt2M;
  433. },
  434. beforeFilesUpload(file) {
  435. if(file.type.indexOf('image')!=-1){
  436. return this.beforeUpload(file)
  437. }
  438. const $ext_list = ['xlsx', 'xls', 'doc', 'docx', 'pdf', 'txt','XLSX','XLS','DOC','DOCX','PDF','TXT'];
  439. const isLt2M = file.size / 1024 / 1024 < 5;
  440. let len = file.name.split('.').length - 1;
  441. const $ext_name = file.name.split('.')[len];
  442. let isFile=$ext_list.indexOf($ext_name) != -1;
  443. if (!isLt2M) {
  444. this.$message.error('文件大小不能超过5MB');
  445. }
  446. if (!isFile) {
  447. this.$message.warning('文件格式上传错误,仅支持上传xlsx,xls,doc,docx,pdf,txt)');
  448. }
  449. return isFile && isLt2M;
  450. },
  451. //反馈时间
  452. feedbackTime(item){
  453. this.form.scope_type=item.scope_type;
  454. if(item.scope_type==1){ //每日
  455. this.form[item.timeStr]=item.time
  456. this.form.feedbackTime='每天 '+item.time
  457. }else if(item.scope_type==3||item.scope_type==4){ //每周||每月
  458. this.form[item.dayStr]=item.scope_type_two
  459. this.form[item.timeStr]=item.time
  460. this.form.feedbackTime=`${item.scope_type==3? '每周/':'每月'}${this.returnTimeStr(item)} ${item.time}`
  461. }else{ //其他
  462. this.form.special_date=item.special_date
  463. this.form.feedbackTime=item.special_date
  464. }
  465. },
  466. returnTimeStr(item){
  467. let str='';
  468. if(item.scope_type==3){
  469. switch(item.scope_type_two){
  470. case 1:
  471. str='周一'
  472. break
  473. case 2:
  474. str='周二'
  475. break
  476. case 3:
  477. str='周三'
  478. break
  479. case 4:
  480. str='周四'
  481. break
  482. case 5:
  483. str='周五'
  484. break
  485. case 6:
  486. str='周六'
  487. break
  488. case 7:
  489. str='周日'
  490. break
  491. }
  492. }else{
  493. str=item.scope_type_two+'号'
  494. }
  495. return str
  496. },
  497. showSelectorUser(index){
  498. if(index==1){ //负责人
  499. this.employee_selected.employee=[this.owner_userInfo];
  500. }else if(index==2){ //审批人
  501. this.employee_selected.employee=[this.reviewer_userInfo];
  502. }
  503. this.selectUserIndex=index;
  504. this.show_employee_selector=true;
  505. },
  506. // 部门可见
  507. dept_confirm(data){
  508. this.dept_selected = {dept: [],employee:[]};
  509. let dept_ids = [];
  510. this.form.dept_ids='';
  511. this.deptVisibleName = ''
  512. if (data.dept !== null && data.dept.length != 0) {
  513. this.dept_selected = data
  514. data.dept.forEach(element => {
  515. dept_ids.push(element.dept_id)
  516. this.deptVisibleName += (element.dept_name+',')
  517. });
  518. }
  519. this.form.dept_ids=dept_ids.toString();
  520. },
  521. employee_confirm_all(val){
  522. this.employee_selected_all.employee=val.employee;
  523. let joiner_ids=val.employee.map(item=>{
  524. return item.id
  525. })
  526. this.form.joiner_ids=joiner_ids.toString()
  527. },
  528. employee_confirm(val){
  529. let user=val.employee[0]
  530. this.employee_selected.employee=val.employee;
  531. if(this.selectUserIndex==1){ //创建目标的负责人
  532. this.owner_userInfo=user;
  533. this.form.owner_id=user.id
  534. }else if(this.selectUserIndex==2){ //创建目标的kr负责人
  535. if(user){
  536. this.reviewer_userInfo=user;
  537. this.form.reviewer_id=user.id
  538. }else{
  539. this.reviewer_userInfo={};
  540. this.form.reviewer_id=''
  541. }
  542. }
  543. },
  544. addTab() {
  545. this.tabIndex++;
  546. this.accomplish++;
  547. },
  548. close_before(done) {
  549. this.close();
  550. done();
  551. },
  552. //关闭||清空数据
  553. close() {
  554. this.$emit('update:visible', false);
  555. },
  556. // 确定
  557. confirm() {
  558. if(!this.form.name){
  559. this.$message.error('请输入任务名称');
  560. return false;
  561. }
  562. if(this.form.visible_type==5&&this.form.dept_ids.length==0){
  563. this.$message.error('请选择可见部门');
  564. return false;
  565. }
  566. let params={
  567. name: this.form.name,// 是 计划名
  568. owner_id: this.form.owner_id,// 是 integer 负责人id
  569. level : '1',// 是 string 优先等级 1-最高 2-高 3-中 4-低 5-非常低
  570. visible_type: this.form.visible_type,//是 string 可见范围种类 1-全公司 2-相关成员 5-指定部门可见
  571. target_type: this.target_type,//是 string 计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
  572. target_id: this.id,//是 integer 绑定的对象id 跟对象种类配对使用
  573. start_date: this.form.start_date,//是 string 计划开始日期 格式:2022-01-01
  574. end_date: this.form.end_date,//是 string 计划结束日期 格式:2022-01-01
  575. }
  576. if(this.isShowGl){
  577. if(this.target_id){ //kr
  578. params.target_id=this.target_id;
  579. params.target_type=this.selectTarget_type;
  580. }else{
  581. params.target_type=0;
  582. }
  583. if(this.target_plan_id){ //母任务
  584. params.target_id=this.target_plan_id;
  585. params.target_type=3;
  586. }
  587. }
  588. let filterData={
  589. content:this.form.content,//否 string 计划描述,没有的时候不要上传这个字段,空字符也不行
  590. reviewer_id: this.form.reviewer_id,//否 integer 审批者id,没有的时候不要上传这个字段,空字符也不行
  591. wh: this.form.wh,//否 string 预估工时,没有填写的时候不要上传这个字段,空字符也不行
  592. dept_ids:this.form.dept_ids,// 否 string 部门id列表,以逗号分割,只有可见范围种类为指定部门可见才需要上传这个字段,没有的时候不要上传这个字段,空字符也不行
  593. joiner_ids: this.form.joiner_ids,// 否 string 参与者id列表,以逗号分割,没有的时候不要上传这个字段,空字符也不行
  594. // files: this.form.files,// 否 string 附件列表,以逗号分割,没有的时候不要上传这个字段,空字符也不行
  595. target: this.form.target,// 否 integer 量化配置的目标值,只有配置了量化配置的时候需要上传,没有的时候不要上传这个字段,空字符也不行
  596. unit: this.form.unit,// 否 string 量化配置的单位值,只有配置了量化配置的时候需要上传,没有的时候不要上传这个字段,空字符也不行
  597. feedbackTime:this.form.feedbackTime,
  598. scope_type: this.form.scope_type,// 否 string 反馈配置的时间种类 1-每天 2-每个工作日 3-每周 4-每月 5-今天 6-明天
  599. special_date: this.form.special_date? this.form.special_date+':00':'',// 否 string
  600. daily_time: this.form.daily_time,// 否 string 当反馈配置的时间种类为每天的时候必须传入,否则不要上传这个字段,空字符也不行. 数据格式:23:30:00
  601. work_day_time: this.form.work_day_time,// 否 string 当反馈配置的时间种类为每个工作日的时候必须传入,否则不要上传这个字段,空字符也不行. 数据格式:23:30:00
  602. week_day: this.form.week_day,// 否 integer 当反馈配置的时间种类为每周的时候必须传入,否则不要上传这个字段,空字符也不行. 数值在1-7之间 1-周一 2-周二 3-周三 4-周四 5-周五 6-周六 7-周日
  603. week_day_time: this.form.week_day_time,// 否 string 当反馈配置的时间种类为每周的时候必须传入,否则不要上传这个字段,空字符也不行.数据格式:23:30:00
  604. month_day: this.form.month_day,// 否 string 当反馈配置的时间种类为每月的时候必须传入,否则不要上传这个字段,空字符也不行. 数值在1-31之间,分别代表每月的几号
  605. month_day_time: this.form.month_day_time,// 否 string 当反馈配置的时间种类为每月的时候必须传入,否则不要上传这个字段,空字符也不行.数据格式:23:30:00
  606. }
  607. filterData=this.filterData(filterData)
  608. let files=this.files.map(item=>{
  609. return item.file
  610. })
  611. if(this.files.length>0){
  612. filterData.files=files.toString();
  613. }
  614. params=Object.assign({}, params, JSON.parse(JSON.stringify(filterData)))
  615. this.wait=true;
  616. this.$axiosUser('post', 'api/pro/okr/plan/create', params).then(res => {
  617. this.$message.success('已添加');
  618. this.$emit('confirm', {});
  619. this.close();
  620. }).finally(_=>{
  621. this.wait=false;
  622. })
  623. },
  624. filterData(item){
  625. for (let key in item) {
  626. item[key]=item[key]? item[key]:undefined
  627. }
  628. return item
  629. },
  630. },
  631. created() {
  632. },
  633. };
  634. </script>
  635. <style scoped lang="scss">
  636. .files-box{
  637. margin-right: 10px;
  638. height: 46px;
  639. width: 200px;
  640. padding-left: 10px;
  641. position: relative;
  642. }
  643. .files-box div{
  644. width: 100px;
  645. overflow: hidden;
  646. text-overflow: ellipsis;
  647. white-space: nowrap;
  648. }
  649. .files-box:hover{
  650. background-color: #dcdfe6;
  651. }
  652. .files-box i{
  653. color: #606266;
  654. }
  655. .files-box i:hover{
  656. color: #f56c6c;
  657. }
  658. .showUpdate .el-icon-error:hover{
  659. color: #f56c6c;
  660. }
  661. .el-icon-plus{
  662. width: 40px;
  663. height: 40px;
  664. border-radius: 100%;
  665. border: 1px dashed #909399;
  666. font-size: 18px;
  667. text-align: center;
  668. line-height: 40px;
  669. color: #909399;
  670. }
  671. .bj{
  672. background-color: #fff;
  673. }
  674. .inputDc {
  675. color: #606266;
  676. position: absolute;
  677. border-radius: 4px;
  678. padding: 0 15px;
  679. top: 0;
  680. right: 30px;
  681. left: 0;
  682. bottom: 0;
  683. z-index: 9;
  684. cursor: pointer;
  685. overflow: hidden;
  686. text-overflow: ellipsis;
  687. white-space: nowrap;
  688. }
  689. .border {
  690. -webkit-appearance: none;
  691. background-color: #fff;
  692. background-image: none;
  693. border-radius: 4px;
  694. border: 1px solid #dcdfe6;
  695. -webkit-box-sizing: border-box;
  696. box-sizing: border-box;
  697. color: #C0C4CF;
  698. font-size: inherit;
  699. height: auto;
  700. outline: 0;
  701. padding: 0 15px;
  702. padding-right: 10px;
  703. line-height: 34px;
  704. height: 34px;
  705. width: 400px;
  706. position: relative;
  707. cursor: pointer;
  708. }
  709. .border .font-flex-word{
  710. color: #606266;
  711. }
  712. .border:hover{
  713. border: 1px solid #c0c4cc;
  714. }
  715. .w270{
  716. width: 400px;
  717. }
  718. // ::v-deep .el-form-item__label{
  719. // line-height: 14px;
  720. // padding-bottom: 8px;
  721. // font-weight: 500;
  722. // color: #909399;
  723. // padding-left: 3px;
  724. // }
  725. .add-task-title{
  726. padding: 10px;
  727. position: relative;
  728. color: #141c28;
  729. }
  730. .add-task-title::after{
  731. content: "";
  732. position: absolute;
  733. width: 4px;
  734. height: 14px;
  735. border-radius: 5px;
  736. background-color: #409EFF;
  737. left: 0;
  738. top: 13px;
  739. }
  740. .form {
  741. // margin: 30px 0;
  742. }
  743. ::v-deep .el-form-item {
  744. margin-bottom: 16px;
  745. }
  746. ::v-deep .el-dialog__body {
  747. padding: 20px;
  748. padding-right: 14px;
  749. }
  750. ::v-deep .el-textarea__inner{
  751. min-height: 36px !important;
  752. }
  753. </style>