sealDialog.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <template>
  2. <ele-modal
  3. :visible="visible"
  4. :title="title"
  5. width="65%"
  6. :destroy-on-close="true"
  7. @update:visible="updateVisible"
  8. :maxable="true"
  9. append-to-body
  10. >
  11. <div class="switch" v-if="title == '详情'">
  12. <div class="switch_left">
  13. <ul>
  14. <li
  15. v-for="item in tabOptions"
  16. :key="item.key"
  17. :class="{ active: activeComp == item.key }"
  18. @click="activeComp = item.key"
  19. >
  20. {{ item.name }}
  21. </li>
  22. </ul>
  23. </div>
  24. </div>
  25. <el-form
  26. ref="formRef"
  27. :model="form"
  28. :rules="rules"
  29. label-width="120px"
  30. size="small"
  31. v-show="activeComp == 'main'"
  32. style="margin-top: 15px"
  33. >
  34. <!-- 第一行:印章编码 + 印章名称 -->
  35. <el-row :gutter="20">
  36. <el-col :span="12">
  37. <el-form-item label="印章编码" prop="code">
  38. <el-input
  39. v-model="form.code"
  40. placeholder="系统自动生成,唯一码"
  41. disabled
  42. />
  43. </el-form-item>
  44. </el-col>
  45. <el-col :span="12">
  46. <el-form-item label="印章名称" prop="name" required>
  47. <el-input
  48. v-model="form.name"
  49. placeholder="请输入"
  50. :disabled="title == '详情' || title == '变更'"
  51. clearable
  52. />
  53. </el-form-item>
  54. </el-col>
  55. </el-row>
  56. <!-- 第二行:印章类型 + 印章编号 -->
  57. <el-row :gutter="20">
  58. <el-col :span="12">
  59. <el-form-item label="印章类型" prop="sealType" required>
  60. <DictSelection
  61. dictName="印章类型"
  62. clearable
  63. filterable
  64. v-model="form.sealType"
  65. :isProhibit="title == '详情' || title == '变更'"
  66. >
  67. </DictSelection>
  68. </el-form-item>
  69. </el-col>
  70. <el-col :span="12">
  71. <el-form-item label="印章编号" prop="sealNumber">
  72. <el-input
  73. v-model="form.sealNumber"
  74. placeholder="请输入"
  75. :disabled="title == '详情' || title == '变更'"
  76. clearable
  77. />
  78. </el-form-item>
  79. </el-col>
  80. </el-row>
  81. <!-- 第三行:印章持有人 + 版本 -->
  82. <el-row :gutter="20">
  83. <el-col :span="12">
  84. <el-form-item label="印章持有人" prop="sealHolderName">
  85. <el-input
  86. :maxlength="20"
  87. v-model="form.sealHolderName"
  88. @click.native="setUsers"
  89. placeholder="选择人员"
  90. :disabled="title == '详情'"
  91. />
  92. </el-form-item>
  93. </el-col>
  94. <el-col :span="12">
  95. <el-form-item label="版本" prop="version" required>
  96. <el-input
  97. v-model="form.version"
  98. placeholder="请输入"
  99. :disabled="title == '详情'"
  100. clearable
  101. />
  102. </el-form-item>
  103. </el-col>
  104. </el-row>
  105. <!-- 第四行:是否长期有效 + 状态 -->
  106. <el-row :gutter="20">
  107. <el-col :span="12">
  108. <el-form-item label="是否长期有效" prop="isLongTerm" required>
  109. <el-radio-group
  110. v-model="form.isLongTerm"
  111. :disabled="title == '详情'"
  112. >
  113. <el-radio :label="1">长期</el-radio>
  114. <el-radio :label="0">非长期</el-radio>
  115. </el-radio-group>
  116. </el-form-item>
  117. </el-col>
  118. <!-- <el-col :span="12">
  119. <el-form-item label="状态" prop="status" required>
  120. <el-switch
  121. v-model="form.status"
  122. :disabled="title == '详情'"
  123. :active-value="1"
  124. :inactive-value="0"
  125. />
  126. </el-form-item>
  127. </el-col> -->
  128. </el-row>
  129. <!-- 非长期时显示有效期 -->
  130. <el-row :gutter="20" v-if="form.isLongTerm == '0'">
  131. <el-col :span="12">
  132. <el-form-item label="有效期开始日期" prop="validStartDate">
  133. <el-date-picker
  134. v-model="form.validStartDate"
  135. :disabled="title == '详情'"
  136. type="date"
  137. value-format="yyyy-MM-dd"
  138. style="width: 100%"
  139. />
  140. </el-form-item>
  141. </el-col>
  142. <el-col :span="12">
  143. <el-form-item label="有效期结束日期" prop="validEndDate">
  144. <el-date-picker
  145. v-model="form.validEndDate"
  146. type="date"
  147. value-format="yyyy-MM-dd"
  148. :disabled="title == '详情'"
  149. style="width: 100%"
  150. />
  151. </el-form-item>
  152. </el-col>
  153. </el-row>
  154. <!-- 印章图片上传 -->
  155. <el-row>
  156. <el-col :span="24">
  157. <el-form-item label="印章图片" prop="imgUrl" required>
  158. <div class="upload-container">
  159. <WithView
  160. :assetName="''"
  161. :disabled="title == '详情'"
  162. v-model="form.imgUrl"
  163. style="max-height: 370px"
  164. ></WithView>
  165. <div class="upload-tips">
  166. <p>上传要求:</p>
  167. <p>1、图像样式必须与实物印章的印模规制保持一致。</p>
  168. <p>2、印模必须清晰、完整、无断裂、无拖影</p>
  169. </div>
  170. </div>
  171. </el-form-item>
  172. </el-col>
  173. </el-row>
  174. </el-form>
  175. <template slot="footer">
  176. <el-button
  177. type="primary"
  178. size="small"
  179. @click="handleSave"
  180. v-if="title != '详情'"
  181. >保存</el-button
  182. >
  183. <el-button
  184. type="primary"
  185. size="small"
  186. @click="handleSave('sub')"
  187. v-if="title != '详情'"
  188. >保存并提交</el-button
  189. >
  190. <el-button size="small" @click="handleCancel">取消</el-button>
  191. </template>
  192. <addUser ref="addREf" @changeParent="userBk"></addUser>
  193. <bpmDetail
  194. v-if="activeComp == 'bpm' && form.processInstanceId"
  195. :id="form.processInstanceId"
  196. ></bpmDetail>
  197. <list v-if="activeComp == 'list' && form.id" :sealId="form.id"></list>
  198. <process-submit-dialog
  199. :isNotNeedProcess="false"
  200. :processSubmitDialogFlag.sync="processSubmitDialogFlag"
  201. v-if="processSubmitDialogFlag"
  202. ref="processSubmitDialogRef"
  203. @reload="reload"
  204. ></process-submit-dialog>
  205. </ele-modal>
  206. </template>
  207. <script>
  208. import {
  209. addSeal,
  210. changeSeal,
  211. updateSeal,
  212. getSealById
  213. } from '@/api/sealManagement';
  214. import addUser from '@/views/rulesManagement/earlyWarningRules/components/user-select/user-select.vue';
  215. import WithView from '@/components/upload/WithViewNew.vue';
  216. import bpmDetail from '@/views/bpm/processInstance/businessDetail.vue';
  217. import list from './list.vue';
  218. import processSubmitDialog from '@/components/processSubmitDialog/processSubmitDialog.vue';
  219. const defaultForm = {
  220. code: '',
  221. imgUrl: '',
  222. isLongTerm: 1,
  223. name: '',
  224. remark: '',
  225. sealHolderId: '',
  226. sealHolderName: '',
  227. sealNumber: '',
  228. sealType: 'legal_effect',
  229. sealTypeName: '',
  230. status: 0,
  231. processInstanceId: '',
  232. validEndDate: '',
  233. validStartDate: '',
  234. version: ''
  235. };
  236. export default {
  237. components: { addUser, WithView, bpmDetail, list, processSubmitDialog },
  238. name: 'SealDialog',
  239. data() {
  240. return {
  241. activeComp: 'main',
  242. tabOptions: [
  243. { key: 'main', name: '详情' },
  244. { key: 'bpm', name: '流程详情' },
  245. { key: 'list', name: '使用记录' }
  246. ],
  247. processSubmitDialogFlag: false,
  248. visible: false,
  249. title: '新增',
  250. sealTypeList: [
  251. {
  252. label: '法律效力章',
  253. value: '1'
  254. },
  255. {
  256. label: '财务专用章',
  257. value: '2'
  258. },
  259. {
  260. label: '业务专用章',
  261. value: '3'
  262. },
  263. {
  264. label: '内部管理章',
  265. value: '4'
  266. }
  267. ],
  268. form: {
  269. ...defaultForm
  270. },
  271. rules: {
  272. name: [
  273. { required: true, message: '请输入印章名称', trigger: 'blur' }
  274. ],
  275. sealType: [
  276. { required: true, message: '请选择印章类型', trigger: 'change' }
  277. ],
  278. version: [{ required: true, message: '请输入版本', trigger: 'blur' }],
  279. isLongTerm: [
  280. { required: true, message: '请选择是否长期有效', trigger: 'change' }
  281. ],
  282. status: [
  283. { required: true, message: '请选择状态', trigger: 'change' }
  284. ],
  285. sealHolderId: [
  286. { required: true, message: '请选择', trigger: 'change' }
  287. ],
  288. imgUrl: [
  289. { required: true, message: '请上传印章图片', trigger: 'change' }
  290. ],
  291. validStartDate: [
  292. { required: true, message: '请选择', trigger: 'change' }
  293. ],
  294. validEndDate: [
  295. { required: true, message: '请选择', trigger: 'change' }
  296. ]
  297. }
  298. };
  299. },
  300. methods: {
  301. open(row, type = 'add') {
  302. this.activeComp = 'main';
  303. console.log(type, 'type');
  304. if (row && (type == 'edit' || type == 'modify' || type == 'view')) {
  305. getSealById(row.id).then((res) => {
  306. this.form = res;
  307. if (type == 'modify') {
  308. this.form.parentId = row.id;
  309. }
  310. });
  311. this.title =
  312. type == 'edit' ? '修改' : type == 'modify' ? '变更' : '详情';
  313. } else {
  314. this.title = '新增';
  315. this.resetForm();
  316. }
  317. this.visible = true;
  318. },
  319. setUsers() {
  320. this.$refs.addREf.open();
  321. },
  322. updateVisible(val) {
  323. this.visible = val;
  324. if (!val) {
  325. this.resetForm();
  326. }
  327. },
  328. userBk(data) {
  329. console.log(data, 'data');
  330. this.form.sealHolderId = data.map((item) => item.id).toString();
  331. this.form.sealHolderName = data.map((item) => item.name).toString();
  332. },
  333. resetForm() {
  334. this.form = {
  335. ...defaultForm
  336. };
  337. this.$nextTick(() => {
  338. this.$refs.formRef && this.$refs.formRef.clearValidate();
  339. });
  340. },
  341. // 图片上传
  342. handleImageChange(file) {
  343. const isJPG = file.raw.type === 'image/jpeg';
  344. const isPNG = file.raw.type === 'image/png';
  345. const isBMP = file.raw.type === 'image/bmp';
  346. const isLt10M = file.raw.size / 1024 / 1024 < 10;
  347. if (!isJPG && !isPNG && !isBMP) {
  348. this.$message.error('上传图片只能是 JPG、PNG、BMP 格式!');
  349. return false;
  350. }
  351. if (!isLt10M) {
  352. this.$message.error('上传图片大小不能超过 10MB!');
  353. return false;
  354. }
  355. this.form.sealImage = file.raw;
  356. this.form.sealImageUrl = URL.createObjectURL(file.raw);
  357. },
  358. // 保存
  359. async handleSave(type) {
  360. this.$refs.formRef.validate(async (valid) => {
  361. if (valid) {
  362. let api =
  363. this.title === '新增'
  364. ? addSeal
  365. : this.title === '变更'
  366. ? changeSeal
  367. : updateSeal;
  368. try {
  369. api(this.form).then((res) => {
  370. if (type === 'sub') {
  371. this.sub(this.title == '修改' ? this.form.id : res);
  372. return;
  373. }
  374. this.$message.success('保存成功');
  375. this.$emit('reload');
  376. this.visible = false;
  377. });
  378. } catch (error) {
  379. this.$message.error(error.message || '保存失败');
  380. }
  381. }
  382. });
  383. },
  384. async sub(res) {
  385. let data = await getSealById(res);
  386. this.processSubmitDialogFlag = true;
  387. this.$nextTick(() => {
  388. let params = {
  389. businessId: data.id,
  390. businessKey: 'main_seal_management_approval',
  391. formCreateUserId: data.createUserId,
  392. variables: {
  393. businessCode: data.code,
  394. businessName: data.name,
  395. businessType: '印章审核'
  396. }
  397. };
  398. this.$refs.processSubmitDialogRef.init(params);
  399. });
  400. },
  401. reload() {
  402. this.$emit('reload');
  403. this.visible = false;
  404. },
  405. // 取消
  406. handleCancel() {
  407. this.visible = false;
  408. }
  409. }
  410. };
  411. </script>
  412. <style scoped>
  413. .upload-container {
  414. display: flex;
  415. align-items: flex-start;
  416. gap: 20px;
  417. }
  418. .seal-uploader {
  419. width: 200px;
  420. height: 200px;
  421. border: 1px dashed #d9d9d9;
  422. border-radius: 6px;
  423. cursor: pointer;
  424. position: relative;
  425. overflow: hidden;
  426. background-color: #f5f7fa;
  427. display: flex;
  428. align-items: center;
  429. justify-content: center;
  430. }
  431. .seal-uploader:hover {
  432. border-color: #409eff;
  433. }
  434. .uploader-placeholder {
  435. text-align: center;
  436. color: #8c939d;
  437. }
  438. .uploader-placeholder .el-icon-picture-outline {
  439. font-size: 48px;
  440. margin-bottom: 10px;
  441. }
  442. .upload-text {
  443. display: flex;
  444. gap: 10px;
  445. justify-content: center;
  446. }
  447. .delete-btn {
  448. color: #f56c6c;
  449. }
  450. .seal-image {
  451. width: 100%;
  452. height: 100%;
  453. object-fit: contain;
  454. }
  455. .upload-tips {
  456. flex: 1;
  457. font-size: 12px;
  458. color: #606266;
  459. line-height: 1.8;
  460. }
  461. .upload-tips p {
  462. margin: 0;
  463. padding: 0;
  464. }
  465. .upload-tips p:first-child {
  466. font-weight: bold;
  467. margin-bottom: 5px;
  468. }
  469. </style>