交通管理局公文项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

734 lines
27 KiB

6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
3 weeks ago
6 days ago
6 days ago
3 weeks ago
6 days ago
6 days ago
6 days ago
6 days ago
3 weeks ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
6 days ago
3 weeks ago
6 days ago
3 weeks ago
6 days ago
3 weeks ago
6 days ago
3 weeks ago
6 days ago
6 days ago
  1. <template>
  2. <div class="app-container row-container">
  3. <div class="filing-cabinet-wrapper">
  4. <div class="file-cabinet">
  5. <div class="cabinet-grid">
  6. <div class="cabinet-column">
  7. <div
  8. v-for="(item, index) in cabinetColumns[0]"
  9. :key="'col1-' + index"
  10. :class="['cabinet-cell', { 'cabinet-cell-ld': item.type === 'ld', 'cabinet-cell-department': item.type === 'department', 'cabinet-cell-big': item.type === 'big', 'cabinet-cell-selected': selectedCell === item.id, 'cabinet-cell-unbound': !item.bound }]"
  11. @click="selectCell(item)"
  12. >
  13. <span class="cell-id">{{ item.id }}</span>
  14. <!-- <span v-if="item.type === 'ld'" class="cell-label">{{ item.bound ? item.borrowName : '' }}</span> -->
  15. <span class="cell-label">{{ item.bound ? item.borrowName : '' }}</span>
  16. <span v-if="item.documentCount > 0" class="cell-file-count">{{ item.documentCount }}</span>
  17. </div>
  18. </div>
  19. <div class="cabinet-column">
  20. <div
  21. v-for="(item, index) in cabinetColumns[1]"
  22. :key="'col2-' + index"
  23. :class="['cabinet-cell', { 'cabinet-cell-ld': item.type === 'ld', 'cabinet-cell-department': item.type === 'department', 'cabinet-cell-big': item.type === 'big', 'cabinet-cell-selected': selectedCell === item.id, 'cabinet-cell-unbound': !item.bound }]"
  24. @click="selectCell(item)"
  25. >
  26. <span class="cell-id">{{ item.id }}</span>
  27. <span class="cell-label">{{ item.bound ? item.borrowName : '' }}</span>
  28. <span v-if="item.documentCount > 0" class="cell-file-count">{{ item.documentCount }}</span>
  29. </div>
  30. </div>
  31. <div class="cabinet-column">
  32. <div
  33. v-for="(item, index) in cabinetColumns[2]"
  34. :key="'col3-' + index"
  35. :class="['cabinet-cell', { 'cabinet-cell-ld': item.type === 'ld', 'cabinet-cell-department': item.type === 'department', 'cabinet-cell-big': item.type === 'big', 'cabinet-cell-selected': selectedCell === item.id, 'cabinet-cell-unbound': !item.bound }]"
  36. @click="selectCell(item)"
  37. >
  38. <span class="cell-id">{{ item.id }}</span>
  39. <span class="cell-label">{{ item.bound ? item.borrowName : '' }}</span>
  40. <span v-if="item.documentCount > 0" class="cell-file-count">{{ item.documentCount }}</span>
  41. </div>
  42. </div>
  43. <div class="cabinet-column">
  44. <div
  45. v-for="(item, index) in cabinetColumns[3]"
  46. :key="'col4-' + index"
  47. :class="['cabinet-cell', { 'cabinet-cell-ld': item.type === 'ld', 'cabinet-cell-department': item.type === 'department', 'cabinet-cell-big': item.type === 'big', 'cabinet-cell-selected': selectedCell === item.id, 'cabinet-cell-unbound': !item.bound }]"
  48. @click="selectCell(item)"
  49. >
  50. <span class="cell-id">{{ item.id }}</span>
  51. <span class="cell-label">{{ item.bound ? item.borrowName : '' }}</span>
  52. <span v-if="item.documentCount > 0" class="cell-file-count">{{ item.documentCount }}</span>
  53. </div>
  54. </div>
  55. </div>
  56. </div>
  57. <div class="content-wrap">
  58. <div v-if="selectedCellInfo" class="cabinet-info">
  59. <div class="cabinet-info-title">
  60. <p class="title-left">层位信息</p>
  61. </div>
  62. <div style="display: flex; justify-content: space-between; align-items: center;">
  63. <div style="display: flex; justify-content: flex-start;">
  64. <div class="info-row">
  65. <span class="info-label">编号</span>
  66. <span class="info-value">{{ selectedCellInfo.id }}</span>
  67. </div>
  68. <div class="info-row">
  69. <span class="info-label">绑定状态</span>
  70. <span :class="['info-value', !selectedCellInfo.bound ? 'unbound' : '']">
  71. {{ selectedCellInfo.bound ? '已绑定' : '未绑定' }}
  72. </span>
  73. </div>
  74. <div class="info-row">
  75. <span class="info-label">绑定目标</span>
  76. <span class="info-value">
  77. {{ selectedCellInfo.bound ? selectedCellInfo.borrowName : '-' }}
  78. </span>
  79. </div>
  80. </div>
  81. <div>
  82. <el-button v-if="!selectedCellInfo.bound" size="mini" @click="borrowerListVisible = true">
  83. <i class="iconfont icon-bendiguajie" />
  84. 绑定
  85. </el-button>
  86. <el-button v-else :loading="unbindLoading" class="unbind-btn" size="mini" @click="unbindCell">
  87. <i class="iconfont icon-jiebang" />
  88. 解绑
  89. </el-button>
  90. </div>
  91. </div>
  92. </div>
  93. <div class="container-wrap">
  94. <span class="right-top-line" />
  95. <span class="left-bottom-line" />
  96. <div class="cabinet-table-title">
  97. <p class="title-left">在架信息</p>
  98. <span> <i style="color: #1890ff; font-weight: bold;">{{ miodData.length }}</i> </span>
  99. </div>
  100. <el-table
  101. ref="table"
  102. v-loading="tableLoading"
  103. class="archives-table"
  104. :data="miodData"
  105. style="width: 100%;"
  106. height="calc(100vh - 334px)"
  107. @cell-dblclick="tableDoubleClick"
  108. >
  109. <el-table-column type="index" label="序号" width="60" />
  110. <el-table-column prop="regNo" label="收文号" width="120" />
  111. <el-table-column prop="detailsType" label="文件类型" width="100">
  112. <template slot-scope="scope">
  113. <el-tag v-if="scope.row.detailsType === 1">原件</el-tag>
  114. <el-tag v-else>复印件</el-tag>
  115. </template>
  116. </el-table-column>
  117. <el-table-column prop="maintitle" label="公文题名" min-width="140" show-overflow-tooltip />
  118. <el-table-column prop="docNo" label="来文字号" min-width="120" />
  119. <el-table-column prop="docDepartment" label="所属文件" width="120" />
  120. <el-table-column prop="actual_return_time" label="操作" align="center" width="140">
  121. <template slot-scope="scope">
  122. <el-button size="mini" style="padding: 5px;" :loading="removalLoaing[scope.$index]" @click="handleBatchDel(scope.$index, scope.row)">
  123. <i class="iconfont icon-xiajia" />
  124. 手动下架
  125. </el-button>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. </div>
  130. </div>
  131. </div>
  132. <el-dialog :close-on-click-modal="false" :modal-append-to-body="false" append-to-body title="绑定借阅者" :visible.sync="borrowerListVisible">
  133. <div class="setting-dialog">
  134. <div style="display: flex; justify-content: flex-start; margin-bottom: 15px;">
  135. <el-input v-model="query.search" clearable size="small" placeholder="输入借阅者名称搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="handleSearch" />
  136. <el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" style="margin-left: 10px;" @click="handleSearch">搜索</el-button>
  137. <el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetSearch">重置</el-button>
  138. </div>
  139. <el-table
  140. ref="borrowerTable"
  141. v-loading="borrowerListLoading"
  142. :data="borrowerList"
  143. row-key="id"
  144. height="440px"
  145. >
  146. <el-table-column prop="borrowName" label="借阅者名称" />
  147. <el-table-column prop="borrowType" label="借阅者类型">
  148. <template slot-scope="scope">
  149. <div>
  150. <span v-if="scope.row.borrowType === 1">部门</span>
  151. <span v-if="scope.row.borrowType === 2">个人</span>
  152. </div>
  153. </template>
  154. </el-table-column>
  155. <el-table-column prop="borrowNo" label="借阅证号">
  156. <template slot-scope="scope">
  157. {{ scope.row.borrowNo || '-' }}
  158. </template>
  159. </el-table-column>
  160. <el-table-column prop="cabinetId" label="已绑定位置">
  161. <template slot-scope="scope">
  162. {{ scope.row.cabinetId ? String(scope.row.cabinetId).padStart(2, '0') : '-' }}
  163. </template>
  164. </el-table-column>
  165. <el-table-column prop="create_time" label="操作" width="80">
  166. <template slot-scope="scope">
  167. <el-button :disabled="scope.row.cabinetId !== null" :loading="bindLoading[scope.$index]" size="mini" style="padding: 5px;" @click="handleBindCell(scope.$index, scope.row)"> {{ scope.row.cabinetId ? '已绑定' : '绑定' }}</el-button>
  168. </template>
  169. </el-table-column>
  170. </el-table>
  171. <el-pagination
  172. :current-page="borrowerPage.current+1"
  173. :page-size="borrowerPage.size"
  174. :total="borrowerPage.total"
  175. :page-sizes="[10, 20, 50, 100]"
  176. layout="total, prev, pager, next, sizes"
  177. @size-change="handleBorrowerSizeChange"
  178. @current-change="handleBorrowerPageChange"
  179. />
  180. </div>
  181. </el-dialog>
  182. <MidoArchivesInfo ref="archivesInfo" :is-mido-record="true" :parent-info="parentInfo" :page-type="pageType" />
  183. </div>
  184. </template>
  185. <script>
  186. import CRUD, { presenter, crud } from '@crud/crud'
  187. import { FetchInitBorrowerList } from '@/api/system/borrower'
  188. import { FetchCabinetBingBorrower, FetchCabinetUnbingBorrower, FetchDocumentCirculationCabinetById, FetchUnpublish } from '@/api/system/documentArchives'
  189. import MidoArchivesInfo from '@/views/archivesMIOD/miodLibrary/module/detail'
  190. import { mapGetters } from 'vuex'
  191. export default {
  192. name: 'FilingCabinet',
  193. components: { MidoArchivesInfo },
  194. mixins: [presenter(), crud()],
  195. cruds() {
  196. return CRUD({
  197. url: 'api/documentCirculationCabinet/initDocumentCirculationCabinet',
  198. title: '文件流转柜管理',
  199. optShow: {
  200. add: false,
  201. edit: false,
  202. del: false,
  203. download: false,
  204. reset: false,
  205. group: false
  206. }
  207. })
  208. },
  209. data() {
  210. return {
  211. tableLoading: false,
  212. categoryId: null,
  213. parentInfo: null,
  214. pageType: 'miodRecord',
  215. removalLoaing: [],
  216. selectedCell: null,
  217. selectedCellInfo: null,
  218. unbindLoading: false,
  219. cabinetColumns: [
  220. [
  221. { id: '01', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  222. { id: '02', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  223. { id: '03', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  224. { id: '04', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  225. { id: '05', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  226. { id: '06', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  227. { id: '07', borrowName: '', type: 'ld', bound: false, documentCount: 0 },
  228. { id: '08', borrowName: '', type: 'big', bound: false, documentCount: 0 }
  229. ],
  230. [
  231. { id: '09', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  232. { id: '10', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  233. { id: '11', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  234. { id: '12', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  235. { id: '13', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  236. { id: '14', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  237. { id: '15', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  238. { id: '16', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  239. { id: '17', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  240. { id: '18', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  241. { id: '19', borrowName: '', type: 'big', bound: false, documentCount: 0 }
  242. ],
  243. [
  244. { id: '20', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  245. { id: '21', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  246. { id: '22', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  247. { id: '23', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  248. { id: '24', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  249. { id: '25', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  250. { id: '26', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  251. { id: '27', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  252. { id: '28', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  253. { id: '29', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  254. { id: '30', borrowName: '', type: 'big', bound: false, documentCount: 0 }
  255. ],
  256. [
  257. { id: '31', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  258. { id: '32', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  259. { id: '33', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  260. { id: '34', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  261. { id: '35', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  262. { id: '36', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  263. { id: '37', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  264. { id: '38', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  265. { id: '39', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  266. { id: '40', borrowName: '', type: 'department', bound: false, documentCount: 0 },
  267. { id: '41', borrowName: '', type: 'big', bound: false, documentCount: 0 }
  268. ]
  269. ],
  270. borrowerListVisible: false,
  271. borrowerList: [],
  272. borrowerListLoading: false,
  273. borrowerPage: {
  274. current: 0,
  275. size: 10,
  276. total: 0
  277. },
  278. query: {
  279. search: ''
  280. },
  281. bindLoading: [],
  282. lastSelectedCellId: null,
  283. miodData: []
  284. }
  285. },
  286. computed: {
  287. ...mapGetters([
  288. 'baseApi'
  289. ])
  290. },
  291. watch: {
  292. },
  293. created() {
  294. },
  295. mounted() {
  296. this.getBorrowerList()
  297. },
  298. methods: {
  299. selectCell(item) {
  300. if (item.type === 'empty') return
  301. this.selectedCell = item.id
  302. this.selectedCellInfo = item
  303. this.getDocumentCirculationCabinetById()
  304. },
  305. [CRUD.HOOK.beforeRefresh]() {
  306. this.crud.params.page = undefined
  307. this.crud.params.size = undefined
  308. },
  309. [CRUD.HOOK.afterRefresh](crud) {
  310. if (crud.data && Array.isArray(crud.data)) {
  311. this.transformCabinetData(crud.data)
  312. }
  313. },
  314. transformCabinetData(data) {
  315. const ldCells = []
  316. const departmentCells = []
  317. const bigCells = []
  318. data.forEach(item => {
  319. const cell = {
  320. id: String(item.id).padStart(2, '0'),
  321. type: item.cabinetType === 1 ? 'ld' : (item.cabinetType === 3 ? 'big' : 'department'),
  322. documentCount: item.documentCount || 0,
  323. bound: !!item.bindBorrower,
  324. borrowName: item.borrowName || '',
  325. borrowerType: item.borrowerType,
  326. originalData: item
  327. }
  328. if (item.cabinetType === 1) {
  329. ldCells.push(cell)
  330. } else if (item.cabinetType === 3) {
  331. bigCells.push(cell)
  332. } else {
  333. departmentCells.push(cell)
  334. }
  335. })
  336. ldCells.sort((a, b) => parseInt(a.id) - parseInt(b.id))
  337. departmentCells.sort((a, b) => parseInt(a.id) - parseInt(b.id))
  338. bigCells.sort((a, b) => parseInt(a.id) - parseInt(b.id))
  339. this.cabinetColumns = [
  340. [...ldCells, bigCells[0]],
  341. [...departmentCells.slice(0, 10), bigCells[1]],
  342. [...departmentCells.slice(10, 20), bigCells[2]],
  343. [...departmentCells.slice(20, 30), bigCells[3]]
  344. ]
  345. this.$nextTick(() => {
  346. // 优先选中上次操作的格子,否则选中第一个
  347. if (this.lastSelectedCellId) {
  348. let targetCell = null
  349. for (const column of this.cabinetColumns) {
  350. targetCell = column.find(cell => cell.id === this.lastSelectedCellId)
  351. if (targetCell) break
  352. }
  353. if (targetCell) {
  354. this.selectCell(targetCell)
  355. return
  356. }
  357. }
  358. if (this.cabinetColumns[0] && this.cabinetColumns[0][0]) {
  359. this.selectCell(this.cabinetColumns[0][0])
  360. }
  361. })
  362. },
  363. getDocumentCirculationCabinetById() {
  364. this.tableLoading = true
  365. this.miodData = []
  366. const params = {
  367. id: this.selectedCellInfo.originalData.id
  368. }
  369. FetchDocumentCirculationCabinetById(params).then((res) => {
  370. if (res.code !== 500) {
  371. this.miodData = res.detailsList || []
  372. } else {
  373. this.$message({ message: '获取文件流转柜详情失败', type: 'error', offset: 8 })
  374. }
  375. this.tableLoading = false
  376. }).catch(err => {
  377. console.log(err)
  378. this.$message({ message: '获取文件流转柜详情失败', type: 'error', offset: 8 })
  379. this.tableLoading = false
  380. })
  381. },
  382. handleBindCell(index, item) {
  383. this.$set(this.bindLoading, index, true)
  384. this.$confirm('此操作将绑定当前借阅者' + '<span>你是否还要继续?</span>', '提示', {
  385. confirmButtonText: '继续',
  386. cancelButtonText: '取消',
  387. type: 'warning',
  388. dangerouslyUseHTMLString: true
  389. }).then(() => {
  390. const params = {
  391. bindBorrower: item.id,
  392. borrowType: null,
  393. id: this.selectedCellInfo.originalData.id
  394. }
  395. FetchCabinetBingBorrower(params).then((res) => {
  396. if (res.code !== 500) {
  397. this.$message({ message: '绑定成功', type: 'success', offset: 8 })
  398. this.lastSelectedCellId = this.selectedCellInfo.id
  399. this.crud.refresh()
  400. } else {
  401. this.$message({ message: '绑定失败', type: 'error', offset: 8 })
  402. }
  403. this.borrowerListVisible = false
  404. this.getBorrowerList()
  405. }).catch(err => {
  406. console.log(err)
  407. this.borrowerListVisible = false
  408. })
  409. this.$set(this.bindLoading, index, false)
  410. }).catch(() => {
  411. this.$set(this.bindLoading, index, false)
  412. })
  413. },
  414. unbindCell() {
  415. this.unbindLoading = true
  416. this.$confirm('此操作将解绑当前绑定的目标' + '<span>你是否还要继续?</span>', '提示', {
  417. confirmButtonText: '继续',
  418. cancelButtonText: '取消',
  419. type: 'warning',
  420. dangerouslyUseHTMLString: true
  421. }).then(() => {
  422. const ids = [this.selectedCellInfo.originalData.id]
  423. FetchCabinetUnbingBorrower(ids).then((res) => {
  424. if (res.code !== 500) {
  425. this.$message({ message: '解绑成功', type: 'success', offset: 8 })
  426. this.lastSelectedCellId = this.selectedCellInfo.id
  427. this.crud.refresh()
  428. } else {
  429. this.$message({ message: '解绑失败', type: 'error', offset: 8 })
  430. }
  431. this.getBorrowerList()
  432. }).catch(err => {
  433. console.log(err)
  434. })
  435. this.unbindLoading = false
  436. }).catch(() => {
  437. this.unbindLoading = false
  438. })
  439. },
  440. tableDoubleClick(row) {
  441. this.parentInfo = row
  442. this.$nextTick(() => {
  443. this.$refs.archivesInfo.archivesInfoVisible = true
  444. this.$refs.archivesInfo.archivesTabIndex = 0
  445. this.$refs.archivesInfo.getDetial()
  446. })
  447. },
  448. handleSearch() {
  449. this.borrowerPage.current = 0
  450. this.getBorrowerList()
  451. },
  452. resetSearch() {
  453. this.query.search = ''
  454. this.borrowerPage.current = 0
  455. this.getBorrowerList()
  456. },
  457. getBorrowerList() {
  458. this.borrowerListLoading = true
  459. const params = {
  460. page: this.borrowerPage.current,
  461. size: this.borrowerPage.size,
  462. search: this.query.search
  463. }
  464. FetchInitBorrowerList(params).then(res => {
  465. if (res && res.content) {
  466. this.borrowerList = res.content || []
  467. this.borrowerPage.total = res.totalElements || 0
  468. } else {
  469. this.borrowerList = []
  470. this.borrowerPage.total = 0
  471. }
  472. this.borrowerListLoading = false
  473. }).catch(err => {
  474. console.error('获取借阅者列表失败:', err)
  475. this.borrowerList = []
  476. this.borrowerPage.total = 0
  477. this.borrowerListLoading = false
  478. })
  479. },
  480. handleBorrowerPageChange(page) {
  481. this.borrowerPage.current = page - 1
  482. this.getBorrowerList()
  483. },
  484. handleBorrowerSizeChange(size) {
  485. this.borrowerPage.size = size
  486. this.borrowerPage.current = 0
  487. this.getBorrowerList()
  488. },
  489. handleBatchDel(index, data) {
  490. this.$set(this.removalLoaing, index, true)
  491. this.$confirm('此操作将下架当前公文' + '<span>你是否还要继续?</span>', '提示', {
  492. confirmButtonText: '继续',
  493. cancelButtonText: '取消',
  494. type: 'warning',
  495. dangerouslyUseHTMLString: true
  496. }).then(() => {
  497. const params = {
  498. 'documentTid': data.regNo
  499. }
  500. FetchUnpublish(params).then((res) => {
  501. if (res.code !== 500) {
  502. this.$message({ message: '手动下架成功', type: 'success', offset: 8 })
  503. this.crud.refresh()
  504. } else {
  505. this.$message({ message: '手动下架失败', type: 'error', offset: 8 })
  506. }
  507. }).catch(err => {
  508. console.log(err)
  509. })
  510. this.$set(this.removalLoaing, index, false)
  511. }).catch(() => {
  512. this.$set(this.removalLoaing, index, false)
  513. })
  514. }
  515. }
  516. }
  517. </script>
  518. <style lang="scss" scoped>
  519. @import "~@/assets/styles/collect-reorganizi.scss";
  520. ::v-deep .el-pagination{
  521. margin: 24px 0 10px 0 !important
  522. }
  523. .filing-cabinet-wrapper {
  524. display: flex;
  525. justify-content: flex-start;
  526. }
  527. .file-cabinet {
  528. border-radius: 8px;
  529. padding: 15px;
  530. box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
  531. margin-right: 20px;
  532. height: calc(100vh - 180px);
  533. }
  534. .cabinet-grid {
  535. display: flex;
  536. gap: 8px;
  537. height: 100%;
  538. }
  539. .cabinet-column {
  540. display: flex;
  541. flex-direction: column;
  542. gap: 8px;
  543. flex: 1;
  544. }
  545. .cabinet-column:nth-child(1) .cabinet-cell:not(.cabinet-cell-big) {
  546. flex: 1;
  547. min-height: 0;
  548. width: 100px;
  549. }
  550. .cabinet-column:nth-child(2) .cabinet-cell:not(.cabinet-cell-big),
  551. .cabinet-column:nth-child(3) .cabinet-cell:not(.cabinet-cell-big),
  552. .cabinet-column:nth-child(4) .cabinet-cell:not(.cabinet-cell-big) {
  553. flex: 1;
  554. min-height: 0;
  555. width: 100px;
  556. }
  557. .cabinet-column .cabinet-cell-big {
  558. height: 140px;
  559. width: 100px;
  560. }
  561. .cabinet-cell {
  562. border-radius: 4px;
  563. display: flex;
  564. flex-direction: column;
  565. justify-content: center;
  566. align-items: center;
  567. cursor: pointer;
  568. transition: all 0.3s ease;
  569. border: 1px solid #d9d9d9;
  570. position: relative;
  571. overflow: hidden;
  572. }
  573. .cabinet-cell-empty {
  574. background: #fff;
  575. border: 1px dashed #d9d9d9;
  576. cursor: default;
  577. }
  578. .cabinet-cell-ld {
  579. background: linear-gradient(145deg, #fff 0%, #f0f0f0 100%);
  580. }
  581. .cabinet-cell-department {
  582. background: linear-gradient(145deg, #f5f7fa 0%, #e4e8ec 100%);
  583. }
  584. .cabinet-cell-unbound {
  585. background: linear-gradient(145deg, #fafafa 0%, #e8e8e8 100%);
  586. opacity: 0.6;
  587. }
  588. .cabinet-cell-unbound .cell-label {
  589. color: #999;
  590. }
  591. .cabinet-cell:hover:not(.cabinet-cell-empty) {
  592. border-color: #1890ff;
  593. box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3);
  594. }
  595. .cabinet-cell-selected {
  596. border-color: #1890ff;
  597. background: linear-gradient(145deg, #e6f7ff 0%, #b3d9ff 100%);
  598. box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  599. }
  600. .cell-label {
  601. font-size: 12px;
  602. color: #333;
  603. font-weight: 500;
  604. text-align: center;
  605. padding: 0 4px;
  606. }
  607. .cell-id {
  608. position: absolute;
  609. top: 2px;
  610. left: 4px;
  611. font-size: 10px;
  612. color: #333;
  613. }
  614. .cell-file-count {
  615. position: absolute;
  616. bottom: 2px;
  617. right: 4px;
  618. font-size: 11px;
  619. color: #1890ff;
  620. font-weight: bold;
  621. // background: rgba(24, 144, 255, 0.1);
  622. padding: 1px 4px;
  623. border-radius: 4px;
  624. }
  625. .cabinet-info {
  626. // display: flex;
  627. // justify-content: space-between;
  628. // align-items: center;
  629. // margin-top: 15px;
  630. padding: 12px;
  631. background: #fff;
  632. border-radius: 6px;
  633. border: 1px solid #e8e8e8;
  634. }
  635. .info-row {
  636. display: flex;
  637. margin-right: 20px;
  638. font-size: 14px;
  639. &:last-child {
  640. margin-right: 0;
  641. }
  642. }
  643. .info-label {
  644. color: #999;
  645. }
  646. .info-value {
  647. color: #333;
  648. font-weight: 500;
  649. }
  650. .info-value.unbound {
  651. color: #ED4A41;
  652. }
  653. .content-wrap {
  654. width: calc(100% - 454px);
  655. }
  656. [data-theme=light] .el-button.unbind-btn,
  657. [data-theme=light] .el-button.unbind-btn:hover,
  658. [data-theme=light] .el-button.unbind-btn:focus{
  659. color: #ED4A41;
  660. border-color: #ED4A41;
  661. background: transparent;
  662. }
  663. [data-theme=light] .el-button.unbind-btn.is-disabled,
  664. [data-theme=light] .el-button.unbind-btn.is-disabled:hover,
  665. [data-theme=light] .el-button.unbind-btn.is-disabled:focus{
  666. color:#F6A5A0;
  667. border-color:#F6A5A0;
  668. background: rgba(252,49,49,0.2);
  669. }
  670. .cabinet-info-title{
  671. display: flex;
  672. justify-content: space-between;
  673. align-items: center;
  674. width: 100%;
  675. margin-bottom: 6px;
  676. font-size: 14px;
  677. }
  678. .cabinet-table-title{
  679. font-size: 14px;
  680. display: flex;
  681. justify-content: space-between;
  682. align-items: center;
  683. padding: 12px;
  684. background: #fff;
  685. border-radius: 6px;
  686. border: 1px solid #e8e8e8;
  687. margin-bottom: 12px;
  688. }
  689. .title-left{
  690. display: flex;
  691. justify-content: flex-start;
  692. align-items: center;
  693. color: #000;
  694. &::before{
  695. content: '';
  696. display: inline-block;
  697. width: 4px;
  698. height: 16px;
  699. background: #1890ff;
  700. margin-right: 6px;
  701. }
  702. }
  703. </style>