popbox.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. <template>
  2. <div>
  3. <div class="cellBlock">
  4. <div class="username">姓名</div>
  5. <div class="cellInp">
  6. <el-input
  7. v-model="recordData.studentName"
  8. disabled
  9. placeholder="请输入内容"
  10. ></el-input>
  11. </div>
  12. </div>
  13. <div class="cellBlock">
  14. <div class="username">班级</div>
  15. <div>
  16. <el-tooltip placement="top">
  17. <div slot="content">{{ recordData.className }}</div>
  18. <el-input
  19. v-model="recordData.className"
  20. disabled
  21. placeholder="请输入内容"
  22. ></el-input>
  23. </el-tooltip>
  24. </div>
  25. </div>
  26. <div class="cellBlock">
  27. <div class="username">关联</div>
  28. <div>
  29. <el-select
  30. multiple
  31. collapse-tags
  32. v-model="recordData.contact"
  33. placeholder="请选择关联同学"
  34. >
  35. <el-option
  36. v-for="(item, index) in studentList"
  37. :key="index"
  38. :label="item.name"
  39. :value="item.id"
  40. ></el-option>
  41. </el-select>
  42. </div>
  43. </div>
  44. <div class="cellBlock">
  45. <div class="username">学期</div>
  46. <div>
  47. <el-select v-model="recordData.term" placeholder="请选择">
  48. <el-option
  49. v-for="item in termList"
  50. :key="item.id"
  51. :label="item.name"
  52. :value="item.id"
  53. >
  54. </el-option>
  55. </el-select>
  56. <!-- <el-input
  57. v-model="recordData.semName"
  58. placeholder="请输入内容"
  59. ></el-input> -->
  60. </div>
  61. </div>
  62. <div class="cellBlock">
  63. <div class="username">维度</div>
  64. <div>
  65. <el-select
  66. multiple
  67. collapse-tags
  68. v-model="recordData.type"
  69. placeholder="请选择维度"
  70. >
  71. <el-option
  72. v-for="(item, index) in weiList"
  73. :key="index"
  74. :label="item.name"
  75. :value="item.id"
  76. ></el-option>
  77. </el-select>
  78. </div>
  79. </div>
  80. <div class="cellBlock">
  81. <div class="username">时间</div>
  82. <div>
  83. <el-date-picker
  84. v-model="recordData.recordDate"
  85. type="datetime"
  86. value-format="yyyy-MM-dd HH:mm"
  87. placeholder="选择日期时间"
  88. style="width: 400px;"
  89. >
  90. </el-date-picker>
  91. </div>
  92. </div>
  93. <div class="cellBlock">
  94. <div class="username">地点</div>
  95. <div>
  96. <el-input
  97. v-model="recordData.place"
  98. placeholder="请输入内容"
  99. ></el-input>
  100. </div>
  101. </div>
  102. <div class="cellBlock">
  103. <div class="username">观察内容</div>
  104. <div>
  105. <el-input
  106. v-model="recordData.recordTit"
  107. placeholder="请输入内容"
  108. ></el-input>
  109. </div>
  110. </div>
  111. <div style="margin: 15px 0;width: 70px;font-size: 16px;text-align: right;">
  112. 观察记录
  113. </div>
  114. <div style="width: 500px;">
  115. <el-input
  116. type="textarea"
  117. placeholder="请输入内容"
  118. resize="none"
  119. rows="6"
  120. v-model="recordData.recordContent"
  121. >
  122. </el-input>
  123. </div>
  124. <div style="margin: 15px 0;width: 70px;font-size: 16px;">
  125. 图片
  126. </div>
  127. <div class="imgBlock">
  128. <div
  129. class="imgCell"
  130. v-if="judgeNum"
  131. @click.stop="addImg($event)"
  132. style="cursor: pointer;"
  133. >
  134. +
  135. <input
  136. type="file"
  137. accept="image/*"
  138. multiple
  139. style="display: none"
  140. @change="beforeUpload($event)"
  141. />
  142. </div>
  143. <div
  144. class="imgCell"
  145. v-for="(i, index) in recordData.recordImg"
  146. :key="index"
  147. @click.stop="previewImg(i)"
  148. >
  149. <img class="imgCellCon" :src="i" alt="" />
  150. <div v-if="judgeNum" class="imgDelBtn" @click.stop="delImg(i)">
  151. ×
  152. </div>
  153. </div>
  154. </div>
  155. <div style="width: 500px;display: flex;justify-content: flex-end;">
  156. <div class="updateCordSty" v-if="judgeNum == 1" @click="open">修改</div>
  157. <div class="updateCordSty" v-if="judgeNum == 2" @click="addRecordOpen">
  158. 添加
  159. </div>
  160. </div>
  161. <div v-if="proVisible" class="mask">
  162. <div class="progressBox">
  163. <div class="lbox"><img src="@/assets/loading.gif" />上传中,请稍后</div>
  164. <div style="margin-bottom: 10px">
  165. <span>{{ isFinishSize }}M</span>
  166. /
  167. <span>{{ isAllSize }}M</span>
  168. </div>
  169. <el-progress
  170. :text-inside="true"
  171. :stroke-width="20"
  172. :percentage="progress ? progress : 0"
  173. style="width: 80%"
  174. ></el-progress>
  175. </div>
  176. </div>
  177. </div>
  178. </template>
  179. <script>
  180. export default {
  181. props: {
  182. judgeNum: {
  183. type: Number,
  184. default: 0
  185. },
  186. sUserId: {
  187. type: String,
  188. },
  189. recordDataCopy: {
  190. type: Object,
  191. default: () => {
  192. return {};
  193. }
  194. },
  195. termList: {
  196. type: Array,
  197. default: () => {
  198. return [];
  199. }
  200. },
  201. weiList: {
  202. type: Array,
  203. default: () => {
  204. return [];
  205. }
  206. },
  207. studentList: {
  208. type: Array,
  209. default: () => {
  210. return [];
  211. }
  212. }
  213. },
  214. data() {
  215. return {
  216. recordData: {},
  217. imgList: [],
  218. uploadProgress: 0,
  219. // Progress: false,
  220. proVisible: false,
  221. progress: 0,
  222. inputShow: false,
  223. isFinishSize: 0,
  224. isAllSize: 0
  225. };
  226. },
  227. methods: {
  228. previewImg(url) {
  229. this.$hevueImgPreview(url);
  230. },
  231. addRecordOpen() {
  232. if (!this.recordData.type.length) {
  233. this.$message({
  234. message: "请选择纬度",
  235. type: "warning"
  236. });
  237. return;
  238. }
  239. // console.log(this.recordData.recordDates);
  240. if (!this.recordData.recordDate) {
  241. this.$message({
  242. message: "请选择时间",
  243. type: "warning"
  244. });
  245. return;
  246. }
  247. // return
  248. this.$confirm("是否添加新纪录?", "提示", {
  249. confirmButtonText: "确定",
  250. cancelButtonText: "取消"
  251. })
  252. .then(() => {
  253. this.addRecord();
  254. })
  255. .catch(() => {});
  256. },
  257. // 添加新纪录
  258. addRecord() {
  259. let params = [
  260. {
  261. uid: this.sUserId,
  262. tid: this.$route.query.userid,
  263. contact: this.recordData.contact.join(","),
  264. type: this.recordData.type.join(","),
  265. timing: this.recordData.recordDate,
  266. place: this.recordData.place,
  267. observeCon: this.recordData.recordTit,
  268. recordCon: this.recordData.recordContent,
  269. imgList: this.recordData.recordImg.join(","),
  270. term: this.recordData.term,
  271. pid: 1
  272. }
  273. ];
  274. // console.log("添加新纪录", params);
  275. this.ajax
  276. .post(this.$store.state.api + "insertRecord", params)
  277. .then(res => {
  278. // console.log(res);
  279. this.$emit('updatePanelB',Date.parse(new Date()))
  280. this.$emit("closePop");
  281. this.$emit("getData");
  282. this.$message({
  283. type: "success",
  284. message: "添加成功"
  285. });
  286. });
  287. },
  288. // 确认修改记录提示?
  289. open() {
  290. // console.log(this.recordData);
  291. if (!this.recordData.type.length) {
  292. this.$message({
  293. message: "请选择纬度",
  294. type: "warning"
  295. });
  296. return;
  297. }
  298. // console.log(this.recordData.recordDates);
  299. if (!this.recordData.recordDate) {
  300. this.$message({
  301. message: "请选择时间",
  302. type: "warning"
  303. });
  304. return;
  305. }
  306. // return
  307. this.$confirm("是否修改?", "提示", {
  308. confirmButtonText: "确定",
  309. cancelButtonText: "取消"
  310. })
  311. .then(() => {
  312. this.updateCord();
  313. })
  314. .catch(() => {
  315. this.$message({
  316. type: "info",
  317. message: "已取消修改"
  318. });
  319. });
  320. },
  321. // 修改记录
  322. updateCord() {
  323. let params = [
  324. {
  325. rid: this.recordData.rid,
  326. tid: this.$route.query.userid,
  327. contact: this.recordData.contact.join(","),
  328. type: this.recordData.type.join(","),
  329. timing: this.recordData.recordDate,
  330. place: this.recordData.place,
  331. observeCon: this.recordData.recordTit,
  332. recordCon: this.recordData.recordContent,
  333. imgList: this.recordData.recordImg.join(","),
  334. term: this.recordData.term,
  335. pid: 1
  336. }
  337. ];
  338. // console.log("修改记录", params);
  339. this.ajax
  340. .post(this.$store.state.api + "updateRecordData", params)
  341. .then(res => {
  342. // console.log(res);
  343. this.$emit("closePop");
  344. this.$emit("getData");
  345. this.$message({
  346. type: "success",
  347. message: "修改成功"
  348. });
  349. });
  350. // updateRecordData
  351. },
  352. // 删除图片
  353. delImg(e) {
  354. // console.log("删除图片", e);
  355. this.$confirm("是否删除?", "提示", {
  356. confirmButtonText: "确定",
  357. cancelButtonText: "取消"
  358. })
  359. .then(() => {
  360. const iii = this.recordData.recordImg.indexOf(e);
  361. this.recordData.recordImg.splice(iii, 1);
  362. // this.$message({
  363. // type: "success",
  364. // message: "已修改"
  365. // });
  366. })
  367. .catch(() => {
  368. // this.$message({
  369. // type: "info",
  370. // message: "已取消修改"
  371. // });
  372. });
  373. // this.recordData.recordImg = this.recordData.recordImg.
  374. },
  375. addImg(e) {
  376. var el = e.currentTarget;
  377. el.getElementsByTagName("input")[0].click();
  378. e.target.value = "";
  379. },
  380. beforeUpload(event, type) {
  381. // const loading = this.openLoading();
  382. var file = "";
  383. for (let cfindex = 0; cfindex < event.target.files.length; cfindex++) {
  384. console.log("event.target.files", event.target.files);
  385. file = event.target.files[cfindex];
  386. var credentials = {
  387. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  388. secretAccessKey: "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"
  389. }; //秘钥形式的登录上传
  390. window.AWS.config.update(credentials);
  391. window.AWS.config.region = "cn-northwest-1"; //设置区域
  392. var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
  393. var imgA = [
  394. "png",
  395. "jpg",
  396. "jpeg",
  397. "bmp",
  398. "gif",
  399. "webp",
  400. "psd",
  401. "svg",
  402. "tiff"
  403. ];
  404. if (
  405. imgA.indexOf(file.name.split(".")[file.name.split(".").length - 1]) ==
  406. -1
  407. ) {
  408. this.$message.error("图片格式错误");
  409. return;
  410. }
  411. this.imgLoading = true;
  412. var _this = this;
  413. this.inputShow = false;
  414. this.progress = 0;
  415. this.proVisible = true;
  416. this.isFinishSize = 0;
  417. this.isAllSize = (file.size / 1024 / 1024).toFixed(2);
  418. _this.$forceUpdate();
  419. if (file) {
  420. var params = {
  421. Key:
  422. file.name.split(".")[0] +
  423. new Date().getTime() +
  424. "." +
  425. file.name.split(".")[file.name.split(".").length - 1],
  426. ContentType: file.type,
  427. Body: file,
  428. "Access-Control-Allow-Credentials": "*",
  429. ACL: "public-read"
  430. }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
  431. var options = {
  432. partSize: 2048 * 1024 * 1024,
  433. queueSize: 2,
  434. leavePartsOnError: true
  435. };
  436. bucket
  437. .upload(params, options)
  438. .on("httpUploadProgress", function(evt) {
  439. //这里可以写进度条
  440. _this.progress = parseInt((evt.loaded / evt.total) * 100);
  441. _this.isFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
  442. _this.$forceUpdate();
  443. })
  444. .send(function(err, data) {
  445. _this.imgLoading = false;
  446. // loading.close();
  447. _this.progress = 100;
  448. _this.isFinishSize = _this.isAllSize;
  449. _this.$forceUpdate();
  450. setTimeout(() => {
  451. _this.proVisible = false;
  452. _this.$forceUpdate();
  453. }, 1000);
  454. _this.inputShow = true;
  455. if (err) {
  456. _this.$message.error("上传失败");
  457. } else {
  458. _this.recordData.recordImg.push(data.Location);
  459. _this.$forceUpdate();
  460. // console.log(_this.checkJson);
  461. // console.log(data.Location);
  462. }
  463. });
  464. }
  465. }
  466. // var file = event.target.files[0];
  467. }
  468. },
  469. watch: {
  470. recordDataCopy: {
  471. handler: function(newVal, oldVal) {
  472. this.recordData = JSON.parse(JSON.stringify(this.recordDataCopy));
  473. },
  474. deep: true
  475. }
  476. },
  477. mounted() {
  478. this.recordData = JSON.parse(JSON.stringify(this.recordDataCopy));
  479. // console.log("??????????????????????????????????", this.recordData);
  480. }
  481. };
  482. </script>
  483. <style scoped>
  484. .popbox {
  485. padding: 10px;
  486. border-radius: 10px;
  487. box-shadow: 0 0 10px #ccc;
  488. }
  489. .mask {
  490. background-color: rgb(0 0 0 / 30%);
  491. /* position: fixed; */
  492. position: absolute;
  493. top: 0;
  494. left: 0;
  495. width: 100%;
  496. height: 100%;
  497. z-index: 90;
  498. display: flex;
  499. align-items: center;
  500. justify-content: center;
  501. }
  502. .progressBox {
  503. width: 300px;
  504. height: 150px;
  505. background: #fff;
  506. border-radius: 10px;
  507. box-shadow: 0 0 6px 1px #bfbfbf;
  508. display: flex;
  509. align-items: center;
  510. justify-content: center;
  511. flex-direction: column;
  512. position: relative;
  513. color: #6c6c6c;
  514. }
  515. .progressBox >>> .el-progress-bar__outer {
  516. background-color: #d1dfff !important;
  517. }
  518. .progressBox .lbox {
  519. height: 50px;
  520. font-size: 19px;
  521. display: flex;
  522. align-items: center;
  523. color: #747474;
  524. }
  525. .progressBox .lbox img {
  526. width: 40px;
  527. margin-right: 20px;
  528. }
  529. .tit {
  530. width: 100%;
  531. text-align: center;
  532. margin-bottom: 10px;
  533. }
  534. .cellBlock {
  535. width: 500px;
  536. box-sizing: border-box;
  537. padding: 10px 0;
  538. display: flex;
  539. /* justify-content: center; */
  540. align-items: center;
  541. }
  542. .cellBlock > .username {
  543. width: 70px;
  544. flex-shrink: 0;
  545. font-size: 16px;
  546. text-align: right;
  547. margin-right: 10px;
  548. display: flex;
  549. justify-content: flex-end;
  550. /* justify-content: space-between; */
  551. }
  552. .cellBlock >>> .el-input__inner {
  553. width: 400px;
  554. }
  555. .imgBlock {
  556. width: 500px;
  557. display: flex;
  558. justify-content: flex-start;
  559. flex-wrap: wrap;
  560. }
  561. .imgCell {
  562. position: relative;
  563. width: 100px;
  564. height: 100px;
  565. margin-right: 10px;
  566. margin-bottom: 10px;
  567. display: flex;
  568. justify-content: center;
  569. align-items: center;
  570. border: #ccc 1px solid;
  571. }
  572. .imgCell > .imgDelBtn {
  573. position: absolute;
  574. right: 5px;
  575. top: 5px;
  576. width: 15px;
  577. height: 15px;
  578. border-radius: 50%;
  579. background-color: #fff;
  580. cursor: pointer;
  581. display: flex;
  582. justify-content: center;
  583. align-items: center;
  584. }
  585. .imgCellCon {
  586. width: 100%;
  587. height: 100%;
  588. display: block;
  589. }
  590. .updateCordSty {
  591. cursor: pointer;
  592. padding: 10px 0;
  593. width: 120px;
  594. transform: translate(50%, 0%);
  595. /* float: right; */
  596. background-color: rgba(17, 61, 221, 0.5);
  597. border-radius: 5px;
  598. color: #fff;
  599. display: flex;
  600. justify-content: center;
  601. align-items: center;
  602. }
  603. /* .shadow {
  604. position: absolute;
  605. left: 0;
  606. top: 0;
  607. width: 100%;
  608. height: 100%;
  609. } */
  610. /* ::v-deep .el-input__inner {
  611. width: 200px;
  612. }
  613. ::v-deep .el-select {
  614. width: 200px !important;
  615. } */
  616. /* .conCant {
  617. position: relative;
  618. border: 1px solid #ccc;
  619. width: 200px;
  620. min-height: 40px;
  621. display: flex;
  622. align-items: center;
  623. position: relative;
  624. box-sizing: border-box;
  625. padding: 0 10px;
  626. } */
  627. /* .conCantTxt {
  628. display: flex;
  629. justify-content: flex-start;
  630. margin-right: 5px;
  631. flex-wrap: wrap;
  632. position: relative;
  633. } */
  634. /* .tactList {
  635. position: absolute;
  636. left: 0;
  637. top: 110%;
  638. width: 200px;
  639. height: 200px;
  640. overflow-y: scroll;
  641. background-color: #fff;
  642. border: 1px solid #ccc;
  643. z-index: 10;
  644. box-sizing: border-box;
  645. padding: 10px;
  646. display: flex;
  647. flex-direction: column;
  648. } */
  649. /* .tactListCell {
  650. display: flex;
  651. justify-content: flex-start;
  652. align-items: center;
  653. box-sizing: border-box;
  654. padding: 2px 5px;
  655. background-color: #ccc;
  656. } */
  657. /* .iSty {
  658. position: absolute;
  659. right: 10px;
  660. top: 50%;
  661. transform: translate(0, -50%);
  662. } */
  663. </style>