dialog.addletter.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <template>
  2. <div class="edu-training-edit">
  3. <DialogCom
  4. :title="title"
  5. @close="onHide"
  6. :visible.sync="isShow"
  7. width="1000px"
  8. >
  9. <div class="page-body">
  10. <el-form
  11. ref="form"
  12. :model="formData"
  13. :rules="formDataRules"
  14. label-width="140px"
  15. >
  16. <el-row>
  17. <el-col :span="12">
  18. <el-form-item label="介绍信编号" prop="letterNo">
  19. <el-input
  20. v-model="formData.letterNo"
  21. placeholder="请输入介绍信编号"
  22. maxlength="15"
  23. />
  24. </el-form-item>
  25. </el-col>
  26. <el-col :span="12">
  27. <el-form-item label="接待机构" prop="receptionOrgIds">
  28. <!-- <org-tree-select v-model="formData.receptionOrgIds" ref="orgTreeSelect" :checkShow="true">-->
  29. <!-- </org-tree-select>-->
  30. <org-select ref="execorgTreeSelect"
  31. v-model="formData.receptionOrgIds"
  32. :limitOrgType="String('')"
  33. >
  34. </org-select>
  35. </el-form-item>
  36. </el-col>
  37. <el-col :span="24">
  38. <el-form-item prop="reasons" label="出入事由">
  39. <el-input
  40. v-model="formData.reasons"
  41. placeholder="请输入出入事由"
  42. maxlength="100"
  43. />
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="12">
  47. <el-form-item prop="range" label="介绍信有效期">
  48. <el-date-picker
  49. v-model="formData.range"
  50. type="daterange"
  51. @change="dateRangeChangedHandler"
  52. range-separator="至"
  53. start-placeholder="有效期开始日期"
  54. end-placeholder="有效期截止日期">
  55. </el-date-picker>
  56. <!-- :picker-options="startDatepickerOptions" -->
  57. <!-- <el-date-picker style="width:100%"
  58. v-model="formData.startTime"
  59. type="date"
  60. placeholder="请选择开具日期"
  61. >
  62. </el-date-picker> -->
  63. </el-form-item>
  64. </el-col>
  65. <el-col :span="12">
  66. <el-form-item prop="effectiveDays" label="有效天数">
  67. <el-input-number style="width: 100%" :disabled='true' v-model="formData.effectiveDays" :min="1" ></el-input-number>
  68. </el-form-item>
  69. </el-col>
  70. <el-col :span="12">
  71. <el-form-item label="上传介绍信附件" ref="letterFile" prop="letterFile">
  72. <!-- <K-file-upload
  73. ref="uploadFile"
  74. :limit=2
  75. :defaultValue="formFileListDefualtValue"
  76. :fileType="letterFileType"
  77. @input="fileListChanged"
  78. v-model="formData.letterFile"
  79. />-->
  80. <!-- <ImageListPreview v-model="userInfo.imgFile"></ImageListPreview> -->
  81. <img-file-upload ref="uploadimage" type="more" :value="formData.letterFile"
  82. @input="imageLetterListChanged"></img-file-upload>
  83. </el-form-item>
  84. </el-col>
  85. <el-col :span="12">
  86. <el-form-item label="备注" prop="description">
  87. <el-input type="textarea"
  88. v-model="formData.description"
  89. :autosize="{ minRows: 8, maxRows: 8 }"
  90. placeholder="请输入备注"
  91. maxlength="100"
  92. />
  93. </el-form-item>
  94. </el-col>
  95. </el-row>
  96. <el-row :gutter="10">
  97. <el-col :span="12">
  98. <h3>
  99. <i class="el-icon-collection-tag"></i>
  100. 人员信息
  101. </h3>
  102. </el-col>
  103. <el-col :offset="8" :span="2">
  104. <h3>
  105. <el-button
  106. type="primary"
  107. icon="el-icon-plus"
  108. size="mini"
  109. @click="handleAddUser"
  110. >新增出入人员</el-button
  111. >
  112. </h3>
  113. </el-col>
  114. </el-row>
  115. <el-table border size="small" :data="formData.userInfos" max-height="500" style="margin-bottom: 10px;">
  116. <el-table-column label="序号" align="center" type="index" width="70" />
  117. <el-table-column label="申请单位" width="100" align="center" prop="companyName" />
  118. <el-table-column label="出入人员" width="100" align="center" prop="userName" />
  119. <el-table-column label="证件类型" width="100" align="center" prop="idType">
  120. <template slot-scope="scope">
  121. <dict-tag :options="dict.type.letter_id_type" :value="scope.row.idType"/>
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="证件号码" width="200" align="center" prop="idCard">
  125. </el-table-column>
  126. <el-table-column label="证件图片" align="center" prop="imgFile">
  127. <template slot-scope="scope">
  128. <ImageListPreview v-model="scope.row.imgFile"></ImageListPreview>
  129. </template>
  130. </el-table-column>
  131. <el-table-column
  132. label="操作"
  133. align="center" width="100"
  134. class-name="small-padding fixed-width"
  135. >
  136. <template slot-scope="scope">
  137. <el-button size="mini" type="text" @click="editUser(scope.row)"
  138. >编辑</el-button
  139. >
  140. <el-button size="mini" type="text" @click="remove(scope.row)"
  141. >删除</el-button
  142. >
  143. </template>
  144. </el-table-column>
  145. </el-table>
  146. </el-form>
  147. </div>
  148. <DialogCom
  149. :title="getUserPageTitle()"
  150. :visible.sync="open"
  151. width="600px"
  152. append-to-body
  153. @close="onHideUser"
  154. >
  155. <el-form
  156. ref="formUser"
  157. :model="userInfo"
  158. :rules="userInfoRules"
  159. label-width="140px"
  160. >
  161. <el-form-item label="申请单位" prop="companyName">
  162. <el-input v-model="userInfo.companyName" maxlength="20" placeholder="请输入申请单位" />
  163. </el-form-item>
  164. <el-form-item label="出入人员" prop="userName">
  165. <el-input v-model="userInfo.userName" maxlength="10" placeholder="请输入出入人员" />
  166. </el-form-item>
  167. <el-form-item label="证件类型" prop="idType">
  168. <el-select style="width:100%" v-model="userInfo.idType" placeholder="请选择证件类型" clearable>
  169. <el-option
  170. v-for="dict in dict.type.letter_id_type"
  171. :key="dict.value"
  172. :label="dict.label"
  173. :value="parseInt(dict.value)"
  174. />
  175. </el-select>
  176. </el-form-item>
  177. <el-form-item label="证件号码" prop="idCard">
  178. <el-input v-model="userInfo.idCard" maxlength="20" placeholder="请输入证件号码" />
  179. </el-form-item>
  180. <el-form-item prop="imgFile" v-if="parseInt(userInfo.idType) === 0" ref="userImgFile" label="上传证件正反面" :rules="[{ required: true,message:'请上传证件正反面'}]">
  181. <!-- <ImageListPreview v-model="userInfo.imgFile"></ImageListPreview> -->
  182. <imgUpload ref="uploadimage" type="more" :value="userInfo.imgFile" :limit=2
  183. @input="imageListChanged"></imgUpload>
  184. </el-form-item>
  185. <el-form-item prop="imgFile" v-else ref="userImgFile" label="上传证件图片" :rules="[{ required: true,message:'请上传证件图片'}]">
  186. <!-- <ImageListPreview v-model="userInfo.imgFile"></ImageListPreview> -->
  187. <imgUpload ref="uploadimage" type="more" :value="userInfo.imgFile" :limit=2
  188. @input="imageListChanged"></imgUpload>
  189. </el-form-item>
  190. </el-form>
  191. <div slot="footer" class="dialog-footer">
  192. <el-button type="primary" @click="submitUser">确 定</el-button>
  193. <el-button @click="onHideUser">取 消</el-button>
  194. </div>
  195. </DialogCom>
  196. <div slot="footer" class="dialog-footer">
  197. <el-button type="primary" @click="submitForm">确 定</el-button>
  198. <el-button @click="onHide">取 消</el-button>
  199. </div>
  200. </DialogCom>
  201. </div>
  202. </template>
  203. <script>
  204. import { mapState, mapMutations } from "vuex";
  205. import {
  206. listLetter,
  207. getLetter,
  208. delLetter,
  209. addLetter,
  210. updateLetter,
  211. } from "@/api/core/letter";
  212. import OrgTreeSelect from "@/components/orgTreeSelect";
  213. import KFileUpload from "@/components/K-FileUpload/index.vue";
  214. import dayjs from "dayjs";
  215. import imgUpload from "@/components/ImageUpload";
  216. import imgFileUpload from "@/components/ImageFileUpload";
  217. import DataRangePicker from "@/components/dateTime/daterange.picker.vue";
  218. import orgSelect from "@/components/orgSelect/zl.orgSelect.vue";
  219. export default {
  220. components: {orgSelect, OrgTreeSelect, KFileUpload, imgUpload,DataRangePicker,imgFileUpload },
  221. data() {
  222. const params = this.$route.params;
  223. return {
  224. id: params ? params.id : null,
  225. isShow: false,
  226. title: "录入介绍信",
  227. formData: this.reset(),
  228. formDataRules: {
  229. reasons: [{ required: true, message: "请输入出入事由" }],
  230. letterNo: [{ required: true, message: "请输入介绍信编号" }],
  231. receptionOrgIds: [{ required: true, message: "请选择接待机构" }],
  232. range:[{ required: true, message: "请选择介绍信有效期" }],
  233. // startTime: [{ required: true, message: "请选择开具日期" }],
  234. // effectiveDays: [{ required: true, message: "请选择有效天数" }],
  235. userInfos: [{ required: true, message: "请添加出入人员" }],
  236. letterFile:[{ required: true, message: "请上传介绍信附件" }],
  237. },
  238. userInfoRules: {
  239. userName: [{ required: true, message: "请输入出入人员" }],
  240. companyName: [{ required: true, message: "请输入申请单位" }],
  241. idType: [{ required: true, message: "请选择证件类型" }],
  242. idCard: [{ required: true, message: "请输入证件号码" }],
  243. //imgFile: [{ required: true, message: "请上传证件图片" }],
  244. },
  245. startDatepickerOptions: {
  246. disabledDate: this.endDisabledDate,
  247. },
  248. // endDatepickerOptions: {
  249. // disabledDate: this.endDisabledDate,
  250. // },
  251. formFileListDefualtValue: [],
  252. open: false,
  253. userInfo: this.resetUserInfo(),
  254. imageList: [],
  255. letterFileType:["jpg", "png", "bmp"]
  256. };
  257. },
  258. dicts: ["letter_status","letter_id_type"],
  259. props: {},
  260. watch: {},
  261. created() {},
  262. computed: {
  263. ...mapState(["loginUser", "org"]),
  264. },
  265. methods: {
  266. ...mapMutations([]),
  267. reset(other = {}) {
  268. return {
  269. reasons: null,
  270. letterNo:null,
  271. receptionOrgIds: [],
  272. range:[],
  273. startTime:new Date(),
  274. endTime:null,
  275. effectiveDays:1,
  276. description: null,
  277. letterFile: [],
  278. userInfos: [],
  279. userPageTitle:null,
  280. type:1,
  281. status:0,
  282. ...other,
  283. };
  284. },
  285. resetUserInfo() {
  286. return {
  287. userName: null,
  288. companyName: null,
  289. idType:0,
  290. idCard: null,
  291. imgFile: null,
  292. };
  293. },
  294. async show(id, other = {}) {
  295. if (id) {
  296. this.title = "编辑介绍信";
  297. this.isShow = true;
  298. this.$nextTick(() => {
  299. this.$refs.form.clearValidate(); // 确保在 DOM 更新之后清除表单验证状态
  300. });
  301. getLetter(id).then((response) => {
  302. // let tempRange=[];
  303. // tempRange.push(dayjs(response.data.startTime));
  304. // tempRange.push(new Date(response.data.endTime));
  305. // response.data.range=tempRange;
  306. this.formData ={ ...response.data,range:[response.data.startTime,response.data.endTime]};
  307. this.formFileListDefualtValue=this.formData.letterFile;
  308. });
  309. }
  310. else
  311. {
  312. this.isShow = true;
  313. this.title = "录入介绍信";
  314. this.formData = this.reset();
  315. }
  316. },
  317. handleAddUser() {
  318. this.userPageTitle = '添加出入人员';
  319. this.open = true;
  320. },
  321. getUserPageTitle(){
  322. return this.userPageTitle;
  323. },
  324. imageListChanged(list) {
  325. this.userInfo.imgFile = list;
  326. this.$refs.userImgFile.clearValidate();
  327. },
  328. imageLetterListChanged(list) {
  329. this.formData.letterFile = list;
  330. this.$refs.letterFile.clearValidate();
  331. },
  332. fileListChanged(list)
  333. {
  334. this.$refs.letterFile.clearValidate();
  335. },
  336. endDisabledDate(time) {
  337. //小于开始日期禁止选择
  338. let startDate = new Date();
  339. startDate.setTime(startDate.getTime() - 3600 * 1000 * 24);
  340. if (this.formData.trainingStartDateTime) {
  341. startDate = new Date(
  342. dayjs(this.formData.trainingStartDateTime).format("YYYY-MM-DD")
  343. );
  344. startDate.setTime(startDate.getTime() - 3600 * 1000 * 24);
  345. }
  346. return time.getTime() < new Date(startDate).getTime();
  347. },
  348. startDateChanged(time) {
  349. if (
  350. dayjs(this.formData.startTime).isAfter(dayjs(this.formData.endTime))
  351. ) {
  352. this.formData.endTime = this.formData.startTime;
  353. }
  354. },
  355. endDateChanged(time) {
  356. if (
  357. dayjs(this.formData.startTime).isAfter(dayjs(this.formData.endTime))
  358. ) {
  359. this.formData.startTime = this.formData.endTime;
  360. }
  361. },
  362. onHide() {
  363. this.isShow = false;
  364. this.formData = this.reset();
  365. //this.$refs["uploadFile"].clearFiles();
  366. this.$nextTick(() => {
  367. this.$refs.form.clearValidate(); // 确保在 DOM 更新之后清除表单验证状态
  368. });
  369. },
  370. onHideUser() {
  371. this.open = false;
  372. this.imageList = [];
  373. this.userInfo = this.resetUserInfo();
  374. },
  375. submitUser() {
  376. this.$refs["formUser"].validate((valid) => {
  377. if (valid) {
  378. this.open = false;
  379. console.log("================", this.userInfo);
  380. let userIndex = this.formData.userInfos.findIndex(x=>x.idCard==this.userInfo.idCard);
  381. if(userIndex>-1)
  382. {
  383. this.formData.userInfos.splice(userIndex, 1);
  384. }
  385. this.formData.userInfos.push(this.userInfo);
  386. this.userInfo = this.resetUserInfo();
  387. this.imageList = [];
  388. }
  389. });
  390. },
  391. submitForm() {
  392. this.$refs["form"].validate((valid) => {
  393. if (valid) {
  394. if (this.formData.userInfos.length <= 0) {
  395. this.$message.error("请添加人员");
  396. return;
  397. }
  398. //判断介绍信是否过期
  399. const inputDate = dayjs(this.formData.startTime);
  400. const newDate = inputDate.add(this.formData.effectiveDays,'day').startOf('day');
  401. const currentDate = dayjs();
  402. if (!dayjs(newDate).isAfter(dayjs(currentDate))){
  403. this.$message.error("介绍信已过有效期,请重新选择开具日期或有效天数!");
  404. return;
  405. }
  406. console.log("================", this.formData);
  407. if (this.formData.id != null) {
  408. updateLetter(this.formData).then((response) => {
  409. this.$modal.msgSuccess("编辑成功");
  410. this.isShow = false;
  411. this.formData = this.reset();
  412. this.$emit("success", this.formData);
  413. });
  414. } else {
  415. addLetter(this.formData).then((response) => {
  416. this.$modal.msgSuccess("新增成功");
  417. this.isShow = false;
  418. this.formData = this.reset();
  419. this.$emit("success", this.formData);
  420. });
  421. }
  422. }
  423. });
  424. },
  425. editUser(row) {
  426. this.userPageTitle = '编辑出入人员'
  427. this.open = true;
  428. this.userInfo = row;
  429. },
  430. remove(row) {
  431. console.log("================", row);
  432. this.formData.userInfos.splice(this.formData.userInfos.indexOf(row), 1);
  433. },
  434. dateRangeChangedHandler()
  435. {
  436. console.log("dateRangeChangedHandler",this.formData.range);
  437. if(this.formData.range)
  438. {
  439. this.formData.startTime=dayjs(this.formData.range[0]).startOf('day');
  440. this.formData.endTime=dayjs(this.formData.range[1]).startOf('day');
  441. this.formData.effectiveDays=dayjs(this.formData.range[1]).diff(dayjs(this.formData.range[0]),'day')+1;
  442. }
  443. else{
  444. this.formData.startTime=null;
  445. this.formData.endTime=null;
  446. this.formData.effectiveDays=1;
  447. }
  448. // console.log("dateRangeChangedHandler",this.formData.range, dayjs(this.formData.range[1]).diff(dayjs(this.formData.range[0]),'day') );
  449. }
  450. },
  451. mounted() {},
  452. };
  453. </script>