knowledgeAddUpdate.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. <template>
  2. <rx-layout>
  3. <div slot="center" style>
  4. <div class="mainContent">
  5. <breadcrumb firstLevel="知识仓库管理" lastLevel="知识管理" />
  6. <div class="body">
  7. <div class="content">
  8. <a-form-model ref="knowledgeRef" :model="knowledgeForm" :rules="knowledgeRules" layout="inline" hideRequiredMark>
  9. <a-form-model-item label="*所选分类:" prop="categoryId">
  10. <a-cascader v-model="knowledgeForm.categoryId"
  11. class="scroll-ckunk"
  12. :popupStyle="{
  13. maxWidth: widthVar + 'px',
  14. 'overflow-x': 'auto'
  15. }"
  16. :getPopupContainer="triggerNode => { return triggerNode.parentNode }"
  17. :disabled="!!pkId"
  18. :options="classifyList"
  19. :fieldNames="{ label: 'name', value: 'pkId', children: 'children' }"
  20. placeholder="请选择"
  21. changeOnSelect />
  22. </a-form-model-item>
  23. <a-form-model-item label="*知识类型:" prop="type">
  24. <a-select v-model="knowledgeForm.type" placeholder="请选择" :disabled="!!pkId">
  25. <a-select-option v-for="(item,index) in knowledgeList" :key="index" :value="item.value">
  26. {{item.label}}
  27. </a-select-option>
  28. </a-select>
  29. </a-form-model-item>
  30. <a-form-model-item label="*知识标题:" prop="titles">
  31. <a-input v-model="knowledgeForm.titles" placeholder="请输入" :disabled="!!pkId" />
  32. </a-form-model-item>
  33. <a-form-model-item prop="author">
  34. <span slot="label">&emsp;&emsp;&ensp;作者</span>
  35. <a-input disabled v-model="knowledgeForm.author" placeholder="请输入" />
  36. </a-form-model-item>
  37. <!-- 知识管理与审核管理查看时 为true不可编辑-->
  38. <a-form-model-item label="*编辑简介:" prop="summary">
  39. <a-input v-model="knowledgeForm.summary" :disabled="!!$route.query.show" type="textarea" :autosize="{minRows: 3, maxRows: 6}" placeholder="请输入(建议100个汉字以内)" />
  40. </a-form-model-item>
  41. <!-- 知识管理与审核管理查看时 为true-->
  42. <a-form-model-item label="编辑正文:" prop="content">
  43. <editor class="editorBox" :disabled="!!$route.query.show" :value.sync="knowledgeForm.content"></editor>
  44. </a-form-model-item>
  45. <a-form-model-item label="上传附件:" prop="attachment" v-if="!knowledgeForm.attachment">
  46. <span v-if="!!$route.query.show">未上传附件</span>
  47. <a-upload-dragger
  48. v-else
  49. name="file"
  50. :headers="headers"
  51. action="/api/api-system/system/core/sysFile/upload"
  52. :showUploadList="false"
  53. @change="handleChange"
  54. :beforeUpload="beforeUpload"
  55. >
  56. <p class="ant-upload-drag-icon">
  57. <a-icon v-if="!loading" type="inbox" />
  58. <a-icon v-else type="loading" />
  59. </p>
  60. <p class="ant-upload-text" v-if="!loading">
  61. 点击或将文件拖拽到这里上传(仅可上传一份
  62. </p>
  63. <p v-else class="ant-upload-text">
  64. 上传中...
  65. </p>
  66. <p class="ant-upload-hint">
  67. 支持扩展名:.doc .docx .pdf .xls .xlsx .pptx
  68. </p>
  69. </a-upload-dragger>
  70. </a-form-model-item>
  71. <!-- <a-form-model-item label="上传附件:" prop="accessory"> -->
  72. <!-- <vab-only-office :option='option' officeHeight="800"></vab-only-office> -->
  73. <!-- </a-form-model-item> -->
  74. <a-form-model-item label="附件下载" prop="pass" v-else>
  75. <div class="accessory-show">
  76. <img :src="wordIcon" alt="">
  77. <span style="">{{ knowledgeForm.attachmentName }}</span>
  78. <rx-button class="clearBtn" :butn-icon="'none'" @click="handleShowClick">查看</rx-button>
  79. <rx-button class="clearBtn" :butn-icon="'none'" v-if="(type == 'knowledgeManageList') && !$route.query.show" @click="handleFileDelClick">删除</rx-button>
  80. <rx-button class="clearBtn" :butn-icon="'none'" @click="handleFileDownloadClick">下载</rx-button>
  81. </div>
  82. </a-form-model-item>
  83. <template v-if="showOnlyOffice">
  84. <vab-only-office :option="option" officeHeight="800"></vab-only-office>
  85. </template>
  86. <!-- 审核管理 审核时-->
  87. <template v-if="!!$route.query.isAudit && (type == 'auditManageList')">
  88. <a-form-model-item label="知识审批:" style="font-size:16px;">
  89. <div style="width:100%;box-sizing:border-box;margin-bottom: 16px;">
  90. <a-radio-group v-model="auditForm.result">
  91. <a-radio value="1">通过</a-radio>
  92. <a-radio value="0">驳回</a-radio>
  93. </a-radio-group>
  94. </div>
  95. <div style="width:100%;box-sizing:border-box">
  96. <a-input v-model="auditForm.remark" type="textarea" :autosize="{minRows: 3, maxRows: 6}" :maxLength="200" placeholder="请输入审批意见" />
  97. </div>
  98. </a-form-model-item>
  99. <!-- 最终节点审 核时 -->
  100. <a-form-model-item v-if="isShowOrg && knowledgeForm.type == 1" prop="actualApproverName">
  101. <span slot="label">&emsp;&emsp;权限</span>
  102. <div @click="showAuditFlag = true">
  103. <a-select v-model="authName" :showArrow="false" :open="false" placeholder="请选择组织部门、职系、职称等授予知识访问权限"></a-select>
  104. </div>
  105. </a-form-model-item>
  106. </template>
  107. <a-row :gutter="24" type="flex" justify="end" style="margin-top: 20px;padding-right:12px;">
  108. <a-button style="margin-right: 20px;" @click="$router.back()">取消</a-button>
  109. <a-button v-if="!!$route.query.isAudit || !pkId" type="primary" @click="handleSaveClick" :loading="saveLoading">保存</a-button>
  110. </a-row>
  111. <a-form-model-item label="审批流程:" style="font-size:16px;">
  112. <div style="width:100%;box-sizing:border-box;margin-top:4px;">
  113. <a-table :columns="approverColumns" :data-source="approverData" :pagination="false">
  114. </a-table>
  115. </div>
  116. </a-form-model-item>
  117. <!-- 知识管理 编辑和查看 -->
  118. <a-form-model-item v-if="type == 'knowledgeManageList' && !!pkId && accessAuthority" label="访问权限:" prop="accessAuthority" style="margin: 20px 0;">
  119. <a-input disabled v-model="accessAuthority" />
  120. </a-form-model-item>
  121. </a-form-model>
  122. </div>
  123. </div>
  124. </div>
  125. <a-modal v-model="showAuditFlag"
  126. width="800"
  127. title="选择"
  128. centered
  129. okText="保存"
  130. @ok="handleSaveOk">
  131. <org-people :isOnlyOrg="false"
  132. style="width:800px;height:65vh;"
  133. @transCheckedTarget="transCheckedTarget"
  134. @returnSequencesInfo="handleSequencesChange"
  135. @returnGradeInfo="handleGradeChange" />
  136. </a-modal>
  137. </div>
  138. </rx-layout>
  139. </template>
  140. <script>
  141. import wordIcon from '@/assets/img/wordIcon.png'
  142. import editor from '../components/editor'
  143. import breadcrumb from '../components/breadcrumb'
  144. import orgPeople from './components/orgPeople'
  145. import vabOnlyOffice from '../components/onlyOffice'
  146. import { ACCESS_TOKEN } from '@/store/mutation-types';
  147. import { getCategoryId } from '../aJs/getClassifyTree'
  148. import api from '@/api/knowledge/manage'
  149. import auditApi from '@/api/knowledge/audit'
  150. import classApi from '@/api/knowledge/classify'
  151. import processApi from '@/api/knowledge/auditProcess'
  152. import initMixin from "../aMixin/initMixin"
  153. export default {
  154. name: 'knowledgeAddUpdate',
  155. mixins: [ initMixin ],
  156. components: {
  157. editor,
  158. breadcrumb,
  159. vabOnlyOffice,
  160. orgPeople
  161. },
  162. data() {
  163. return {
  164. loading:false,
  165. api,
  166. classApi,
  167. saveLoading: false,
  168. wordIcon,
  169. // 知识id
  170. pkId: '',
  171. type: '',
  172. knowledgeForm: {
  173. createBy: '',
  174. categoryId: [],
  175. type: undefined,
  176. titles: '',
  177. author: '',
  178. summary: '',
  179. content: '',
  180. attachment: '',
  181. attachmentName: ''
  182. },
  183. showAuditFlag: false,
  184. showOnlyOffice: false,
  185. auditForm: {
  186. pkId: '',
  187. result:'1',
  188. remark:'',
  189. actualApprover: '',
  190. actualApproverName: '',
  191. organizationId: ''
  192. },
  193. authName: undefined,
  194. accessAuthority: undefined,
  195. isShowOrg: false,
  196. knowledgeList: [
  197. {value: '1', label: '文档知识'},
  198. {value: '2', label: '维基知识'}
  199. ],
  200. knowledgeRules: {
  201. categoryId: [
  202. { required: true, message: '请选择分类', trigger: 'blur' }
  203. ],
  204. type: [
  205. { required: true, message: '请选择知识类型', trigger: 'blur' }
  206. ],
  207. titles: [
  208. { required: true, message: '请输入知识标题', trigger: 'blur' }
  209. ],
  210. summary: [
  211. { required: true, message: '请输入简介', trigger: 'blur' }
  212. ]
  213. },
  214. approverColumns: [
  215. {
  216. title: '流程节点',
  217. dataIndex: 'name',
  218. },
  219. {
  220. title: '审批人',
  221. dataIndex: 'approverName',
  222. },
  223. {
  224. title: '审批状态',
  225. dataIndex: 'approvalStatus',
  226. },
  227. {
  228. title: '审批备注',
  229. dataIndex: 'remark',
  230. },
  231. {
  232. title: '时间',
  233. dataIndex: 'approvalTime',
  234. },
  235. ],
  236. approverData: [],
  237. classifyList: [],
  238. option: {
  239. url: '',
  240. canPrint: true,
  241. canDownload:true,
  242. isEdit: '',
  243. fileType: '',
  244. title: '',
  245. lang: '',
  246. isPrint: '',
  247. user: { id:null,name:''}
  248. },
  249. headers: {},
  250. // 组织架构
  251. checkedTarget: {},
  252. // 职系
  253. sequencesInfo: {},
  254. // 职等
  255. gradesInfo: {},
  256. innerWidth: 800
  257. }
  258. },
  259. created() {
  260. this.knowledgeForm = Object.assign({},this.$options.data().knowledgeForm)
  261. this.auditForm = Object.assign({},this.$options.data().auditForm)
  262. let pkId = this.$route.query.pkId
  263. if(pkId) {
  264. this.pkId = pkId
  265. this.type = this.$route.query.type
  266. api.info({pkId:pkId}).then(res => {
  267. this.knowledgeForm.createBy = res.data.createBy
  268. this.knowledgeForm.categoryId = getCategoryId(res.data.knowledgeCategoryAdminVo)
  269. this.knowledgeForm.type = res.data.type.toString()
  270. this.knowledgeForm.titles = res.data.titles
  271. this.knowledgeForm.author = res.data.author
  272. this.knowledgeForm.summary = res.data.summary
  273. this.knowledgeForm.content = res.data.content
  274. this.knowledgeForm.attachment = res.data.attachment
  275. this.knowledgeForm.attachmentName = res.data.attachmentName
  276. this.approverData = res.data.approvals
  277. this.auditForm.actualApprover = this.$store.state.appSetting.user.userId
  278. this.auditForm.actualApproverName = this.$store.state.appSetting.user.fullName
  279. if(res.data.organizationId) {
  280. let organizationInfo = JSON.parse(res.data.organizationId)
  281. let info = []
  282. for(let i of organizationInfo) {
  283. if(i.organizationId) {
  284. info.push(`${i.organizationTree.join('-')}`)
  285. } else if(i.gradeId) {
  286. info.push(`职系-${i.gradeName}`)
  287. } else {
  288. info.push(`职等-${i.gradeLevelName}`)
  289. }
  290. }
  291. this.accessAuthority = info.join('/')
  292. }
  293. // 待最终节点审批
  294. this.isShowOrg = res.data.approvalStatus == 3 ? true : false
  295. })
  296. } else {
  297. this.pkId = ''
  298. this.type = 'knowledgeManageList'
  299. this.knowledgeForm.createBy = this.$store.state.appSetting.user.userId
  300. this.knowledgeForm.author = this.$store.state.appSetting.user.fullName
  301. let queryParam = {
  302. "pageNo": 1,
  303. "pageSize": 1000,
  304. "sortField": "",
  305. "sortOrder": "asc",
  306. "params": {}
  307. }
  308. processApi.findAllApprovalNodes(queryParam).then(res => {
  309. this.approverData = res.result.data.map(item => {
  310. return {
  311. name: item.name,
  312. approverId: item.approverId,
  313. approverName: item.approverName,
  314. isFinal: item.isFinal
  315. }
  316. })
  317. })
  318. }
  319. this.init()
  320. var token = Vue.ls.get(ACCESS_TOKEN);
  321. if (token) {
  322. this.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带token--['Authorization']为自定义key 请根据实际情况自行修改
  323. }
  324. },
  325. mounted() {
  326. let innerWidth = window.innerWidth
  327. // 计算
  328. setTimeout(() => {
  329. let offsetWidth = document.querySelector('.scroll-ckunk').getBoundingClientRect().left
  330. this.widthVar = innerWidth - offsetWidth - 40
  331. }, 1000);
  332. document.onclick=function(element){
  333. if(element.target.className.indexOf('ant-cascader-menu-item')>-1){
  334. document.querySelector('.ant-cascader-menus').scrollLeft = 20480
  335. }
  336. }
  337. /*setInterval(() => {
  338. document.querySelectorAll('.ant-cascader-menu-item').forEach(el => {
  339. el.onclick = function() {
  340. document.querySelector('.ant-cascader-menus').scrollLeft = 2048
  341. }
  342. })
  343. }, 1000)*/
  344. },
  345. beforeDestroy() {
  346. this.$refs.knowledgeRef.clearValidate()
  347. },
  348. methods: {
  349. beforeUpload(file) {
  350. const isLt2M = file.size / 1024 / 1024 < 100;
  351. if (!isLt2M) {
  352. this.$message.error('附件不能超过100M');
  353. return false
  354. }
  355. const fileName = file.name.split('.')
  356. const fileExt = fileName.slice(-1)[0]
  357. let arr = ['doc','docx','pdf','xls','xlsx','pptx']
  358. if(arr.indexOf(fileExt) == -1) {
  359. this.$message.error('仅支持格式.doc .docx .pdf .xls .xlsx .pptx的文件');
  360. return false
  361. }
  362. return true
  363. },
  364. handleChange(info) {
  365. if(info.file.status === 'uploading') {
  366. this.loading = true
  367. return
  368. }
  369. if(info.file.status === 'done') {
  370. this.loading = false
  371. this.knowledgeForm.attachment = info.file.response.data[0].fileId
  372. this.knowledgeForm.attachmentName = info.file.response.data[0].fileName
  373. }
  374. },
  375. // 删除文件
  376. handleFileDelClick() {
  377. this.knowledgeForm.attachment = ''
  378. this.knowledgeForm.attachmentName = ''
  379. },
  380. // 下载文件
  381. handleFileDownloadClick() {
  382. // window.open("/api/api-system/system/core/sysFile/previewFile?fileId="+this.knowledgeForm.attachment)
  383. const link = document.createElement('a')
  384. link.style.display = 'none'
  385. link.href = "/api/api-system/system/core/sysFile/previewFile?fileId="+this.knowledgeForm.attachment
  386. // link.target = '_blank'
  387. link.setAttribute('download', this.knowledgeForm.attachmentName)
  388. document.body.appendChild(link)
  389. link.click()
  390. link.remove()
  391. },
  392. // 保存
  393. handleSaveClick() {
  394. // 新增
  395. if(!this.pkId) {
  396. this.$refs.knowledgeRef.validate(valid => {
  397. if (valid) {
  398. this.saveLoading = true
  399. api.create({...this.knowledgeForm, categoryId: this.knowledgeForm.categoryId.slice(-1)[0]}).then(res => {
  400. if(res.code == 200) {
  401. setTimeout(() =>
  402. {
  403. this.$router.back()
  404. this.saveLoading = false
  405. }
  406. ,1000)
  407. }
  408. })
  409. }
  410. }
  411. )
  412. } else {
  413. // 从知识管理跳进
  414. this.saveLoading = true
  415. if(this.type == 'knowledgeManageList') {
  416. this.$refs.knowledgeRef.validate(valid => {
  417. if (valid) {
  418. api.save({...this.knowledgeForm, categoryId: this.knowledgeForm.categoryId.slice(-1)[0], pkId: this.pkId}).then(res => {
  419. if(res.code == 200) {
  420. setTimeout(() =>
  421. {
  422. this.$router.back()
  423. this.saveLoading = false
  424. }
  425. ,1000)
  426. }
  427. })
  428. }
  429. })
  430. } else {
  431. // 从审核管理跳转
  432. this.auditForm.pkId = this.$route.query.auditId
  433. auditApi.knowledgeApproveById(this.auditForm).then(res => {
  434. if(res.code == 200) {
  435. setTimeout(() =>
  436. {
  437. this.$router.back()
  438. this.saveLoading = false
  439. }
  440. ,1000)
  441. }
  442. })
  443. }
  444. }
  445. },
  446. transCheckedTarget(arg) {
  447. this.checkedTarget = arg
  448. },
  449. handleSequencesChange(arg) {
  450. this.sequencesInfo = arg
  451. },
  452. handleGradeChange(arg) {
  453. this.gradesInfo = arg
  454. },
  455. handleSaveOk() {
  456. if(this.isShowOrg && this.knowledgeForm.type == 1) {
  457. let info = []
  458. let res = []
  459. if(this.checkedTarget.organizationId) {
  460. info.push(`${this.checkedTarget.organizationTree.join('-')}`)
  461. res.push(this.checkedTarget)
  462. }
  463. if(this.sequencesInfo.gradeId) {
  464. info.push(`职系-${this.sequencesInfo.gradeName}`)
  465. res.push(this.sequencesInfo)
  466. }
  467. if(this.gradesInfo.gradeLevelId) {
  468. info.push(`职等-${this.gradesInfo.gradeLevelName}`)
  469. res.push(this.gradesInfo)
  470. }
  471. if(info.length) {
  472. this.authName = info.join('/')
  473. }
  474. if(res.length) {
  475. this.auditForm.organizationId = JSON.stringify([...res])
  476. } else {
  477. this.auditForm.organizationId = ""
  478. }
  479. }
  480. this.showAuditFlag = false
  481. },
  482. handleShowClick() {
  483. this.option.isEdit = false
  484. this.option.lang = 'zh-CN'
  485. // this.option.url = 'http://10.5.100.64:9900/api-system/system/core/sysFile/previewFile?fileId=1597050108435845121'
  486. this.option.url = 'http://10.5.100.101/:8088/api/api-system/system/core/sysFile/previewFile?fileId='+ this.knowledgeForm.attachment,
  487. this.option.title = this.knowledgeForm.attachmentName
  488. this.option.fileType = this.knowledgeForm.attachmentName.split('.').slice(-1)[0]
  489. this.option.isPrint = false
  490. this.showOnlyOffice = true
  491. }
  492. }
  493. }
  494. </script>
  495. <style lang="less" scoped>
  496. @gary: #f8f8f8;
  497. @white: #fff;
  498. .mainContent {
  499. min-height: 100%;
  500. width: 100%;
  501. padding: 40px;
  502. background: #f8f8f8;
  503. position: relative;
  504. .ant-breadcrumb {
  505. position:absolute;
  506. top:10px;
  507. }
  508. .body {
  509. height: 100%;
  510. background: @white;
  511. .content {
  512. height: 100%;
  513. background: @white;
  514. padding: 0 20px 20px;
  515. .ant-form-item {
  516. margin: 8px 0 16px;
  517. }
  518. }
  519. }
  520. }
  521. .accessory-show {
  522. display:flex;
  523. align-items: center;
  524. img {
  525. width: 32px;
  526. height: 32px;
  527. }
  528. span {
  529. margin: 0 40px 0 10px;
  530. }
  531. }
  532. .clearBtn {
  533. background: none;
  534. color: #3294F7;
  535. text-shadow: none;
  536. padding: 0px 6px;
  537. border: none;
  538. box-shadow: none;
  539. }
  540. </style>
  541. <style scoped>
  542. /deep/ .ant-upload.ant-upload-drag {
  543. width: 30%;
  544. background: #fff;
  545. }
  546. /deep/.ant-btn > .anticon + span {
  547. margin-left: 0;
  548. }
  549. /deep/ .ant-cascader-menus {
  550. left: 0!important;
  551. }
  552. /deep/ .ant-cascader-menu:last-child {
  553. margin-right: 0;
  554. }
  555. </style>