index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <template>
  2. <div class="check-task">
  3. <MenuPage only-key="/personal_workbench/check_task" />
  4. <div class="check-main">
  5. <div class="textbook-container">
  6. <div class="title">待审核的教材</div>
  7. <div class="list-header">
  8. <span class="cell">编号</span>
  9. <span class="cell">名称</span>
  10. </div>
  11. <ul class="textbook-list">
  12. <li
  13. v-for="{ id, sn, name } in project_list"
  14. :key="id"
  15. class="textbook-item"
  16. :class="{ active: cur_project_id === id }"
  17. @click="selectProject(id)"
  18. >
  19. <span class="cell">{{ sn }}</span>
  20. <span class="cell">{{ name }}</span>
  21. </li>
  22. </ul>
  23. </div>
  24. <div class="textbook-chapter">
  25. <div ref="chapterHeader" class="chapter-header">
  26. <span class="cell">教材内容</span>
  27. <span class="cell">制作人</span>
  28. <span class="cell">我的审核节点</span>
  29. <span class="cell">状态</span>
  30. <span class="cell">最后编辑人</span>
  31. <span class="cell">最后编辑时间</span>
  32. </div>
  33. <div ref="chapterList" class="chapter-list">
  34. <div
  35. v-for="{
  36. id,
  37. name,
  38. producer_list,
  39. status_name,
  40. deep,
  41. is_my_audit_task,
  42. last_editor_name,
  43. last_edit_time,
  44. is_leaf_chapter,
  45. my_audit_node_desc,
  46. } in node_list"
  47. :key="id"
  48. :style="computedNameStyle(deep, isTrue(is_my_audit_task))"
  49. class="chapter-item"
  50. >
  51. <span
  52. class="path"
  53. :style="computedPathStyle(isTrue(is_my_audit_task))"
  54. @click="navigateToChapter(id, isTrue(is_my_audit_task))"
  55. >
  56. {{ name }}
  57. </span>
  58. <span :title="producer_list.map((producer) => producer.name).join(';')">
  59. {{ producer_list.map((producer) => producer.name).join(';') }}
  60. </span>
  61. <span class="audit-node-desc nowrap-ellipsis" :title="my_audit_node_desc">
  62. {{ my_audit_node_desc }}
  63. </span>
  64. <span class="status">{{ status_name }}</span>
  65. <span>{{ isTrue(is_leaf_chapter) ? last_editor_name : '' }}</span>
  66. <span>{{ isTrue(is_leaf_chapter) ? last_edit_time : '' }}</span>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </template>
  73. <script>
  74. import MenuPage from '../common/menu.vue';
  75. import { ChapterGetBookChapterStructExpandList } from '@/api/book';
  76. import { PageQueryMyProjectList_Auditor } from '@/api/list';
  77. import { isTrue } from '@/utils/validate';
  78. import { getScrollbarWidth } from '@/utils/common';
  79. export default {
  80. name: 'CheckTaskPage',
  81. components: {
  82. MenuPage,
  83. },
  84. data() {
  85. return {
  86. project_list: [],
  87. cur_project_id: '',
  88. node_list: [],
  89. isTrue,
  90. };
  91. },
  92. created() {
  93. this.queryMyProjectList_Auditor();
  94. },
  95. methods: {
  96. /**
  97. * 查询我的审核项目列表
  98. */
  99. queryMyProjectList_Auditor() {
  100. PageQueryMyProjectList_Auditor({ page_capacity: 50, cur_page: 1 }).then(({ project_list }) => {
  101. this.project_list = project_list;
  102. if (this.project_list.length > 0) {
  103. this.cur_project_id = this.project_list[0].id;
  104. this.getBookChapterStructExpandList();
  105. }
  106. });
  107. },
  108. /**
  109. * 得到教材章节结构展开列表
  110. */
  111. getBookChapterStructExpandList() {
  112. ChapterGetBookChapterStructExpandList({
  113. book_id: this.cur_project_id,
  114. node_deep_mode: 0,
  115. is_contain_producer: 'true',
  116. is_contain_auditor: 'true',
  117. }).then(({ node_list }) => {
  118. this.node_list = node_list;
  119. this.$nextTick(() => {
  120. const chapterList = this.$refs.chapterList;
  121. if (chapterList.scrollHeight > chapterList.clientHeight) {
  122. const scrollWidth = getScrollbarWidth();
  123. this.$refs.chapterHeader.style.paddingRight = `${scrollWidth}px`;
  124. } else {
  125. this.$refs.chapterHeader.style.paddingRight = '0';
  126. }
  127. });
  128. });
  129. },
  130. /**
  131. * 选择项目
  132. * @param {string} id - 项目ID
  133. */
  134. selectProject(id) {
  135. this.cur_project_id = id;
  136. this.getBookChapterStructExpandList();
  137. },
  138. /**
  139. * 计算章节名称样式
  140. * @param {number} deep - 节点深度
  141. * @param {boolean} isMyAuditTask - 是否是我的审核任务
  142. * @returns {Object} - 样式对象
  143. */
  144. computedNameStyle(deep, isMyAuditTask) {
  145. return {
  146. 'padding-left': `${(deep - 1) * 16}px`,
  147. fontWeight: deep === 1 ? 'bold' : 'normal',
  148. cursor: isMyAuditTask ? 'pointer' : 'auto',
  149. };
  150. },
  151. /**
  152. * 计算章节路径样式
  153. * @param {boolean} isMyAuditTask - 是否是我的审核任务
  154. * @returns {Object} - 样式对象
  155. */
  156. computedPathStyle(isMyAuditTask) {
  157. return {
  158. color: isMyAuditTask ? '#165dff' : 'default',
  159. };
  160. },
  161. /**
  162. * 导航到章节
  163. * @param {string} id - 章节ID
  164. * @param {boolean} isMyAuditTask - 是否是我的审核任务
  165. */
  166. navigateToChapter(id, isMyAuditTask) {
  167. if (!isMyAuditTask) return;
  168. if (!id) return;
  169. this.$router.push({
  170. path: `/personal_workbench/check_task/audit/${id}`,
  171. query: { project_id: this.cur_project_id },
  172. });
  173. },
  174. },
  175. };
  176. </script>
  177. <style lang="scss" scoped>
  178. @use '@/styles/mixin.scss' as *;
  179. .check-task {
  180. @include page-base;
  181. height: 100%;
  182. .check-main {
  183. display: flex;
  184. flex: 1;
  185. width: 100%;
  186. height: 100%;
  187. border-top: $border;
  188. .textbook-container {
  189. display: flex;
  190. flex-direction: column;
  191. width: 450px;
  192. border-right: $border;
  193. .title {
  194. padding-left: 12px;
  195. font-size: 14px;
  196. font-weight: bold;
  197. color: $font-light-color;
  198. }
  199. .list-header {
  200. display: flex;
  201. align-items: center;
  202. justify-content: space-between;
  203. height: 40px;
  204. padding: 0 12px;
  205. font-size: 14px;
  206. color: $font-light-color;
  207. background-color: #eee;
  208. border-radius: 4px;
  209. .cell {
  210. font-size: 14px;
  211. font-weight: bold;
  212. text-align: center;
  213. &:first-child {
  214. width: 120px;
  215. }
  216. &:last-child {
  217. flex: 1;
  218. }
  219. }
  220. }
  221. .textbook-list {
  222. display: flex;
  223. flex-direction: column;
  224. height: calc(100vh - 184px);
  225. overflow: auto;
  226. .textbook-item {
  227. display: flex;
  228. align-items: center;
  229. height: 40px;
  230. min-height: 40px;
  231. padding: 0 12px;
  232. font-size: 14px;
  233. color: $font-light-color;
  234. cursor: pointer;
  235. background-color: #fff;
  236. border-radius: 4px;
  237. &:hover {
  238. background-color: #f5f5f5;
  239. }
  240. &.active {
  241. background-color: $main-active-color;
  242. }
  243. .cell {
  244. text-align: center;
  245. &:first-child {
  246. width: 120px;
  247. }
  248. &:last-child {
  249. flex: 1;
  250. }
  251. }
  252. }
  253. }
  254. }
  255. .textbook-chapter {
  256. display: flex;
  257. flex: 1;
  258. flex-direction: column;
  259. @mixin cell {
  260. > span {
  261. min-height: 37px;
  262. padding: 8px 12px;
  263. border-right: $border;
  264. }
  265. :first-child {
  266. flex: 1;
  267. border-right: $border;
  268. }
  269. :nth-child(2) {
  270. width: 320px;
  271. text-align: center;
  272. }
  273. :nth-child(3) {
  274. width: 140px;
  275. text-align: center;
  276. }
  277. :nth-child(4) {
  278. width: 140px;
  279. max-width: 140px;
  280. }
  281. :nth-child(5) {
  282. width: 120px;
  283. max-width: 120px;
  284. }
  285. :last-child {
  286. width: 170px;
  287. max-width: 170px;
  288. font-weight: normal;
  289. }
  290. }
  291. .chapter-header {
  292. display: flex;
  293. height: 40px;
  294. font-size: 14px;
  295. background-color: $main-background-color;
  296. border-bottom: $border;
  297. @include cell;
  298. .cell {
  299. font-weight: bold;
  300. text-align: center;
  301. }
  302. }
  303. .chapter-list {
  304. height: calc(100vh - 165px);
  305. overflow: auto;
  306. .chapter-item {
  307. display: flex;
  308. align-items: stretch;
  309. font-size: 14px;
  310. border-bottom: $border;
  311. @include cell;
  312. }
  313. }
  314. }
  315. }
  316. }
  317. </style>