index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <template>
  2. <div>
  3. <van-nav-bar title="填写日报" left-text="返回" @click-left="back" fixed left-arrow/>
  4. <van-form class="login_form" @submit="register">
  5. <van-field readonly clickable name="datetimePicker" :value="form.createDate" label="时间选择" placeholder="点击选择时间"
  6. @click="showPicker = true" :rules="rules.createDate" />
  7. <van-popup v-model="showPicker" position="bottom">
  8. <van-datetime-picker v-model="currentDate" type="date" :min-date="minDate" :max-date="maxDate" @confirm="changeTime" @cancel="showPicker = false"/>
  9. </van-popup>
  10. <!-- <van-cell title="待分配时长" :value="report.time + 'h'" size="large"></van-cell> -->
  11. <div class="form_domains" v-for="(item,index) in form.domains" :key="item.id">
  12. <van-button v-if="index == 0" @click="addNewPro" class="form_addNew" icon="plus" type="info" size="mini">新增项目</van-button>
  13. <van-icon v-else class="form_del" name="delete" @click="delPro(index)" />
  14. <van-cell-group :title="'项目' + (index+1)">
  15. <van-field readonly clickable name="projectId" :value="item.projectName" label="投入项目" placeholder="请选择投入项目" @click="clickPicker(index)"
  16. :rules="[{ required: true, message: '请选择投入项目' }]"/>
  17. <van-popup v-model="showPickerProject" position="bottom">
  18. <van-picker show-toolbar :columns="project" value-key="projectName" @confirm="choseProject" @cancel="showPickerProject = false" />
  19. </van-popup>
  20. <!-- <van-field readonly clickable class="form_input" :value="item.workingTime" name="workingTime" label="工作时长" placeholder="请输入工作时长(单位:小时)"
  21. :rules="[{ required: true, message: '请输入工作时长(单位:小时)' }]" @touchstart.native.stop="showNumberKey = true"/>
  22. <van-number-keyboard v-model="item.workingTime" :show="showNumberKey" close-button-text="完成" extra-key="." :maxlength="4" @blur="showNumberKey = false" /> -->
  23. <!-- 全天上下午模式 -->
  24. <van-field v-if="reportTimeType.type < 2" readonly clickable :value="item.label" label="工作时长" placeholder="请选择工作时长(小时)" @click="clickTimePicker(index)"
  25. :rules="[{ required: true, message: '请选择工作时长' }]"/>
  26. <van-popup v-model="showPickerTime" position="bottom">
  27. <van-picker show-toolbar :columns="timeType" value-key="label" @confirm="choseTimePick" @cancel="showPickerTime = false" />
  28. </van-popup>
  29. <!-- 选择数字时间长度模式 -->
  30. <van-popup v-model="showPickerHours" position="bottom">
  31. <van-picker show-toolbar :columns="timeRange"
  32. :default-index="15"
  33. @confirm="choseTimePick" @cancel="showPickerHours = false" />
  34. </van-popup>
  35. <!-- 时间段选择模式 -->
  36. <van-field readonly v-if="reportTimeType.type == 2" clickable name="datetimePicker" :value="item.startTime" label="开始时间" placeholder="点击选择时间"
  37. @click="showStartTime = true" />
  38. <van-popup v-model="showStartTime" position="bottom">
  39. <van-datetime-picker
  40. v-model="startTime"
  41. type="time"
  42. @confirm="confirmTime(item,0);"
  43. @cancel="showStartTime = false"
  44. :min-hour="8"
  45. :max-hour="23"
  46. :filter="filter"
  47. />
  48. </van-popup>
  49. <van-field v-if="reportTimeType.type == 2" readonly clickable name="datetimePicker" :value="item.endTime" label="结束时间" placeholder="点击选择时间"
  50. @click="showEndTime = true" />
  51. <van-popup v-model="showEndTime" position="bottom" >
  52. <van-datetime-picker
  53. v-model="endTime"
  54. type="time"
  55. :min-hour="8"
  56. :max-hour="23"
  57. :filter="filter"
  58. @confirm="confirmTime(item,1)"
  59. @cancel="showEndTime = false"
  60. />
  61. </van-popup>
  62. <van-field class="form_input"
  63. v-model="item.content" name="content" type="textarea" label="工作事项" placeholder="请输入工作事项"
  64. rows="3" autosize />
  65. </van-cell-group>
  66. </div>
  67. <div class="form_btn" style="margin: 16px;">
  68. <van-button v-if="canEdit" round block type="info" native-type="submit"> 提交 </van-button>
  69. <van-button v-else round block type="info" disabled native-type="submit"> 提交 </van-button>
  70. </div>
  71. </van-form>
  72. <div style="padding:15px;">
  73. <van-button v-if="canCancel" round block type="default" @click="cancel"> 撤销 </van-button>
  74. </div>
  75. <div class="form_tip" v-if="!canEdit"> 当前日报无法修改 </div>
  76. </div>
  77. </template>
  78. <script>
  79. export default {
  80. data() {
  81. return {
  82. canCancel:false,
  83. canEdit:false,
  84. showEndTime: false,
  85. showStartTime: false,
  86. startTime:'09:00',
  87. endTime: '18:00',
  88. nowTime:new Date(),
  89. showPickerHours: false,
  90. timeRange:[0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.5,13.0,13.5,14.0,14.5,15.0],
  91. selectTime:null,
  92. reportTimeType:{},
  93. user: JSON.parse(localStorage.userInfo),
  94. minDate: new Date(2010, 0, 1),
  95. maxDate: new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()),
  96. currentDate: new Date(),
  97. showPickerTime: false,
  98. showPicker: false,
  99. showPickerProject: false,
  100. clickIndex: 0,
  101. clickTimeIndex: 0,
  102. showNumberKey: false,
  103. canClick: 2,
  104. timeType:[],
  105. form: {
  106. createDate: this.format(new Date(new Date()),"yyyy-MM-dd"),
  107. domains: [{
  108. id: null,
  109. projectId: "",
  110. projectName: "",
  111. workingTime: "",
  112. content: "",
  113. state: 2,
  114. }],
  115. },
  116. rules: {
  117. createDate: [{ required: true, message: '请选择填报日期' }],
  118. },
  119. project: [],
  120. report: "",
  121. loading: false,
  122. finished: false
  123. };
  124. },
  125. created() {
  126. },
  127. methods: {
  128. cancel() {
  129. const toast = this.$toast.loading({
  130. forbidClick: true,
  131. duration: 0
  132. });
  133. var ids = '';
  134. var data = this.form.domains;
  135. data.forEach(element => {
  136. if (element.id != null && element.id != '') {
  137. ids +=(element.id+',');
  138. }
  139. });
  140. this.$axios.post("/report/cancel", {userId: this.user.id, reportIds:ids})
  141. .then(res => {
  142. if(res.code == "ok") {
  143. toast.clear();
  144. this.$toast.success('撤销成功');
  145. this.getReport();
  146. } else {
  147. toast.clear();
  148. this.$toast.fail('获取失败');
  149. }
  150. }).catch(err=> {toast.clear();});
  151. },
  152. confirmTime(item, field) {
  153. if (field == 0) {
  154. item.startTime = this.startTime;
  155. this.showStartTime = false;
  156. } else {
  157. item.endTime = this.endTime;
  158. this.showEndTime = false;
  159. }
  160. },
  161. filter(type, options) {
  162. if (type === 'minute') {
  163. return options.filter(option => option % 30 === 0);
  164. }
  165. return options;
  166. },
  167. choseTimePick(value, index) {
  168. //选中时间
  169. if (this.reportTimeType.type == 0) {
  170. this.form.domains[this.clickTimeIndex].timeType = value.value;
  171. this.form.domains[this.clickTimeIndex].workingTime = value.hours;
  172. this.form.domains[this.clickTimeIndex].label = value.label;
  173. this.showPickerTime = false;
  174. } else if (this.reportTimeType.type == 1) {
  175. console.log('this.reportTimeType.type=='+value);
  176. this.form.domains[this.clickTimeIndex].workingTime = value;
  177. this.form.domains[this.clickTimeIndex].label = value.toFixed(1)+'小时';
  178. this.showPickerHours = false;
  179. }
  180. },
  181. clickTimePicker(i) {
  182. this.clickTimeIndex = i;
  183. if (this.reportTimeType.type == 0) {
  184. this.showPickerTime = true;
  185. } else if (this.reportTimeType.type == 1) {
  186. this.showPickerHours = true;
  187. }
  188. },
  189. getTimeType() {
  190. this.$axios.post('/time-type/getCompanyTimeSetting', { companyId: this.user.companyId})
  191. .then(res => {
  192. if(res.code == "ok") {
  193. var t = res.data;
  194. this.reportTimeType = t;
  195. //转化时间格式
  196. if (t.allday != null) {
  197. this.timeType.push({value:0, label:'全天 - '+t.allday+'小时', hours:t.allday});
  198. }
  199. if (t.am != null) {
  200. this.timeType.push({value:1, label:'上午 - '+t.am+'小时', hours: t.am});
  201. }
  202. if (t.pm != null) {
  203. this.timeType.push({value:2, label:'下午 - '+t.pm+'小时', hours: t.pm});
  204. }
  205. } else {
  206. toast.clear();
  207. this.$toast.fail(res.msg);
  208. }
  209. }).catch(err=> {toast.clear();});
  210. },
  211. // 返回
  212. back() {
  213. history.back();
  214. },
  215. // 时间转换
  216. format(date, pattern) {
  217. pattern = pattern || "yyyy-MM-dd";
  218. var _this = this;
  219. return pattern.replace(/([yMdhsm])(\1*)/g, function ($0) {
  220. switch ($0.charAt(0)) {
  221. case 'y': return _this.padding(date.getFullYear(), $0.length);
  222. case 'M': return _this.padding(date.getMonth() + 1, $0.length);
  223. case 'd': return _this.padding(date.getDate(), $0.length);
  224. case 'w': return date.getDay() + 1;
  225. case 'h': return _this.padding(date.getHours(), $0.length);
  226. case 'm': return _this.padding(date.getMinutes(), $0.length);
  227. case 's': return _this.padding(date.getSeconds(), $0.length);
  228. }
  229. });
  230. },
  231. padding(s, len) {
  232. var len = len - (s + '').length;
  233. for (var i = 0; i < len; i++) { s = '0' + s; }
  234. return s;
  235. },
  236. // 获取项目
  237. getProject() {
  238. const toast = this.$toast.loading({
  239. forbidClick: true,
  240. duration: 0
  241. });
  242. this.$axios.post("/project/getProjectList", {})
  243. .then(res => {
  244. if(res.code == "ok") {
  245. toast.clear();
  246. this.project = res.data;
  247. } else {
  248. toast.clear();
  249. this.$toast.fail('获取失败');
  250. }
  251. }).catch(err=> {toast.clear();});
  252. },
  253. // 获取日报
  254. getReport() {
  255. const toast = this.$toast.loading({
  256. forbidClick: true,
  257. duration: 0
  258. });
  259. this.$axios.post("/report/getReport", {date: this.form.createDate})
  260. .then(res => {
  261. if(res.code == "ok") {
  262. toast.clear();
  263. this.report = res.data;
  264. var t = res.data.timeType;
  265. var timeType=[];
  266. //转化时间格式
  267. if (t.allday != null) {
  268. timeType.push({value:0, label:'全天 - '+t.allday+'小时', hours:t.allday});
  269. }
  270. if (t.am != null) {
  271. timeType.push({value:1, label:'上午 - '+t.am+'小时', hours: t.am});
  272. }
  273. if (t.pm != null) {
  274. timeType.push({value:2, label:'下午 - '+t.pm+'小时', hours: t.pm});
  275. }
  276. var list = res.data.report;
  277. if(list.length != 0) {
  278. this.canEdit = false;
  279. this.canCancel = false;
  280. let array = [];
  281. for(var i in list) {
  282. var projectName = "";
  283. for(var j in this.project) {
  284. if(this.project[j].id == list[i].projectId) {
  285. projectName = this.project[j].projectName;
  286. }
  287. }
  288. array.push({
  289. id: list[i].id,
  290. projectId: list[i].projectId,
  291. projectName: projectName,
  292. workingTime: String(list[i].workingTime),
  293. content: list[i].content,
  294. state: list[i].state,
  295. timeType: list[i].timeType,
  296. label: timeType[list[i].timeType].label
  297. })
  298. if (list[i].state >= 2) {
  299. this.canEdit = true;
  300. } else if (list[i].state == 0) {
  301. this.canCancel = true;
  302. }
  303. }
  304. this.form.domains = array;
  305. } else {
  306. //没有填报的可以点击提交
  307. this.form.domains = [{
  308. id: null,
  309. projectId: "",
  310. projectName: "",
  311. workingTime: "",
  312. content: "",
  313. state: 2,
  314. }]
  315. this.canEdit = true;
  316. }
  317. } else {
  318. toast.clear();
  319. this.$toast.fail('获取失败');
  320. }
  321. }).catch(err=> {toast.clear();});
  322. },
  323. // 改变时间
  324. changeTime(time) {
  325. this.form.createDate = this.format(new Date(time),"yyyy-MM-dd");
  326. this.currentDate = time;
  327. this.showPicker = false;
  328. this.getReport();
  329. },
  330. // 选择项目
  331. clickPicker(i) {
  332. this.clickIndex = i;
  333. this.showPickerProject = true;
  334. },
  335. choseProject(value, index) {
  336. this.form.domains[this.clickIndex].projectId = value.id;
  337. this.form.domains[this.clickIndex].projectName = value.projectName;
  338. this.showPickerProject = false;
  339. },
  340. // 添加项目
  341. addNewPro() {
  342. this.form.domains.push({
  343. id: null,
  344. projectId: "",
  345. projectName: "",
  346. workingTime: "",
  347. content: "",
  348. state: 2,
  349. })
  350. },
  351. // 移除项目
  352. delPro(i) {
  353. this.$dialog.confirm({
  354. title: '',
  355. message: '是否移除当前项目'
  356. }).then(() => {
  357. this.form.domains.splice(i,1);
  358. }).catch(() => {
  359. });
  360. },
  361. // 提交日报
  362. register() {
  363. const toast = this.$toast.loading({
  364. forbidClick: true,
  365. duration: 0
  366. });
  367. let formData = new FormData();
  368. if (this.reportTimeType.type == 0) {
  369. var alldayNum = 0;
  370. var amNum = 0;
  371. var pmNum = 0;
  372. for(var i in this.form.domains) {
  373. if (this.form.domains[i].timeType == 0) {
  374. alldayNum ++;
  375. } else if (this.form.domains[i].timeType == 1) {
  376. amNum++;
  377. } else if (this.form.domains[i].timeType == 2) {
  378. pmNum++;
  379. }
  380. }
  381. if (alldayNum > 1) {
  382. this.$toast.fail("工作时间-全天,只能选择一次");
  383. return;
  384. }
  385. if (amNum > 1) {
  386. this.$toast.fail("工作时间-上午,只能选择一次");
  387. return;
  388. }
  389. if (pmNum > 1) {
  390. this.$toast.fail("工作时间-下午,只能选择一次");
  391. return;
  392. }
  393. if (alldayNum == 1 && (amNum > 0 || pmNum > 0)) {
  394. this.$toast.fail("工作时间-全天,不能和上下午同时存在");
  395. return;
  396. }
  397. }
  398. //填字段
  399. for(var i in this.form.domains) {
  400. if (this.form.domains[i].id != null) {
  401. formData.append("id", this.form.domains[i].id);
  402. } else {
  403. formData.append("id", -1);
  404. }
  405. formData.append("projectId", parseFloat(this.form.domains[i].projectId));
  406. formData.append("reportTimeType", this.reportTimeType.type);
  407. if (this.reportTimeType.type == 0) {
  408. formData.append("timeType", this.form.domains[i].timeType);
  409. formData.append("workingTime", parseFloat(this.form.domains[i].workingTime));
  410. } else if (this.reportTimeType.type == 1) {
  411. formData.append("workingTime", parseFloat(this.form.domains[i].workingTime));
  412. } else if (this.reportTimeType.type == 2) {
  413. formData.append("startTime", this.form.domains[i].startTime);
  414. formData.append("endTime",this.form.domains[i].endTime);
  415. }
  416. formData.append("content", this.form.domains[i].content);
  417. formData.append("createDate", this.form.createDate);
  418. }
  419. this.$axios.post("/report/editReport", formData)
  420. .then(res => {
  421. if(res.code == "ok") {
  422. toast.clear();
  423. this.$toast.success('填报成功');
  424. this.$router.push("/index");
  425. } else {
  426. toast.clear();
  427. this.$toast.fail('填报失败');
  428. }
  429. }).catch(err=> {toast.clear();});
  430. },
  431. },
  432. mounted() {
  433. //获取传递过来的日期
  434. var passDate = this.$route.query.date;
  435. if (passDate != null) {
  436. this.form.createDate = this.$route.query.date;
  437. }
  438. this.getProject();
  439. this.getReport();
  440. this.getTimeType();
  441. }
  442. };
  443. </script>
  444. <style lang="less" scope>
  445. .login_form {
  446. margin-top: 46px;
  447. }
  448. .form_domains {
  449. position: relative;
  450. .form_addNew {
  451. position: absolute;
  452. right: 15px;
  453. top: 10px;
  454. }
  455. .form_del {
  456. color: #ff0000;
  457. font-size: 22px;
  458. position: absolute;
  459. right: 15px;
  460. top: 10px;
  461. }
  462. }
  463. .form_tip {
  464. text-align: center;
  465. margin-top: 20px;
  466. color: #afafaf;
  467. font-size: 14px;
  468. }
  469. .card__footer {
  470. padding-top: 10px;
  471. }
  472. .card__tags {
  473. .van-tag {
  474. margin-right: 5px;
  475. }
  476. }
  477. </style>
  478. <style lang="less">
  479. .van-nav-bar .van-icon , .van-nav-bar__text {
  480. color: #20a0ff;
  481. }
  482. </style>