ProjectInfoManage.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <template>
  2. <div class="project-info">
  3. <template
  4. v-if="['/personal_workbench/project', '/project_manage/book', '/project_manage/project'].includes(backPath)"
  5. >
  6. <MenuPage :cur-key="backPath" />
  7. </template>
  8. <template v-if="['org/book', 'org/final', 'org/project'].includes(backPath)">
  9. <ProjectMenu :cur-key="backPath" />
  10. </template>
  11. <div class="project-info__header">
  12. <div class="menu-container">
  13. <span class="name">{{ project.name }}</span>
  14. </div>
  15. <div class="courseware">
  16. <span class="name-path"></span>
  17. <div class="operator">
  18. <span class="link" @click="$router.push({ path: backPath })">返回项目列表</span>
  19. </div>
  20. </div>
  21. </div>
  22. <main class="project-info-manage">
  23. <div class="table-fourcolumn">
  24. <span class="label">项目名称</span>
  25. <div class="project-item">
  26. <span>{{ project.name }}</span>
  27. <span v-if="isManage" class="link" @click="showUpdateField('name', project.name)">更改</span>
  28. </div>
  29. <span class="label">项目分类</span>
  30. <div class="project-item">
  31. <span>{{ project.category }}</span>
  32. <span v-if="isManage" class="link" @click="showUpdateField('category', project.category)">更改</span>
  33. </div>
  34. <span class="label" style="line-height: 290px">教材封面</span>
  35. <div class="project-item">
  36. <div v-if="project.cover_image_file_url?.length > 0" class="cover-image">
  37. <img :src="project.cover_image_file_url" alt="cover image" />
  38. </div>
  39. <div v-else></div>
  40. <span
  41. v-if="isManage"
  42. class="link"
  43. @click="showUpdateField('cover_image_file_url', project.cover_image_file_url)"
  44. >更改</span
  45. >
  46. </div>
  47. <div class="label label-list">
  48. <span>语种</span>
  49. <span>出版单位</span>
  50. <span>作品标签</span>
  51. <span>所属课题</span>
  52. <span>作者</span>
  53. </div>
  54. <div class="project-item info-list">
  55. <div class="info-item">
  56. <span>{{ project.language }}</span>
  57. <span v-if="isManage" class="link" @click="showUpdateField('language', project.language)">更改</span>
  58. </div>
  59. <div class="info-item">
  60. <span>{{ project.publisher }}</span>
  61. <span v-if="isManage" class="link" @click="showUpdateField('publisher', project.publisher)">更改</span>
  62. </div>
  63. <div class="info-item">
  64. <span>
  65. <span v-for="(label, index) in project.label_list" :key="index">
  66. {{ label }}{{ index < project.label_list.length - 1 ? ',' : '' }}
  67. </span>
  68. </span>
  69. <span v-if="isManage" class="link" @click="showUpdateField('label_list', project.label_list)">更改</span>
  70. </div>
  71. <div class="info-item">
  72. <span>{{ project.topic }}</span>
  73. <span v-if="isManage" class="link" @click="showUpdateField('topic', project.topic)">更改</span>
  74. </div>
  75. <div class="info-item">
  76. <span>{{ project.editor }}</span>
  77. <span v-if="isManage" class="link" @click="showUpdateField('editor', project.editor)">更改</span>
  78. </div>
  79. </div>
  80. </div>
  81. <div class="table-twocolumn">
  82. <span class="label">内容简介</span>
  83. <div class="project-item">
  84. <span>{{ project.content_intro }}</span>
  85. <span v-if="isManage" class="link" @click="showUpdateField('content_intro', project.content_intro)">
  86. 更改
  87. </span>
  88. </div>
  89. <span class="label">选题背景</span>
  90. <div class="project-item">
  91. <span>{{ project.background }}</span>
  92. <span v-if="isManage" class="link" @click="showUpdateField('background', project.background)">更改</span>
  93. </div>
  94. <span class="label">作者简介</span>
  95. <div class="project-item">
  96. <span>{{ project.author_intro }}</span>
  97. <span v-if="isManage" class="link" @click="showUpdateField('author_intro', project.author_intro)">更改</span>
  98. </div>
  99. </div>
  100. <div class="table-fourcolumn">
  101. <span class="label" style="line-height: 16px">预计容量<br />(课数)</span>
  102. <div class="project-item">
  103. <span>{{ project.content_count_YG }}</span>
  104. <span v-if="isManage" class="link" @click="showUpdateField('content_count_YG', project.content_count_YG)">
  105. 更改</span
  106. >
  107. </div>
  108. <span class="label">预计字数</span>
  109. <div class="project-item">
  110. <span>{{ project.word_count_YG }}</span>
  111. <span v-if="isManage" class="link" @click="showUpdateField('word_count_YG', project.word_count_YG)">
  112. 更改</span
  113. >
  114. </div>
  115. <span class="label">计划出版日期</span>
  116. <div class="project-item">
  117. <span>{{ project.plan_publish_date }}</span>
  118. <span v-if="isManage" class="link" @click="showUpdateField('plan_publish_date', project.plan_publish_date)">
  119. 更改</span
  120. >
  121. </div>
  122. <span class="label">读者对象</span>
  123. <div class="project-item">
  124. <span>{{ project.reader }}</span>
  125. <span v-if="isManage" class="link" @click="showUpdateField('reader', project.reader)">更改</span>
  126. </div>
  127. <span class="label">项目组长</span>
  128. <div class="project-item">
  129. <span>{{ project.leader_name_desc }}</span>
  130. <span v-if="isManage" class="link" @click="selectLeader">更改</span>
  131. </div>
  132. <span class="label">项目成员</span>
  133. <div class="project-item">
  134. <span>{{ project.member_name_desc }}</span>
  135. <span v-if="isManage" class="link" @click="selectMembers">更改</span>
  136. </div>
  137. <span class="label">创建人</span>
  138. <div class="project-item">
  139. <span>{{ project.creator_name }}</span>
  140. </div>
  141. <span class="label">创建时间</span>
  142. <div class="project-item">
  143. <span>{{ project.create_time }}</span>
  144. </div>
  145. </div>
  146. </main>
  147. <SelectMembers
  148. :visible.sync="visibleMembers"
  149. :title="selectMembersTitle"
  150. :selected-list="list[type]"
  151. :type="type"
  152. @confirm="handleSelectedMembers"
  153. />
  154. <UpdateProjectField
  155. :visible.sync="visibleUpdateField"
  156. :project-id="id"
  157. :field="curField"
  158. :value="curFieldValue"
  159. @updateProjectFieldValue="updateProjectFieldValue"
  160. />
  161. </div>
  162. </template>
  163. <script>
  164. import {
  165. GetProjectInfo,
  166. SetProjectMember,
  167. SetProjectLeader,
  168. UpdateProjectFieldValue,
  169. SetProjectLabel,
  170. } from '@/api/project';
  171. import { GetUserList_ID } from '@/api/user';
  172. import SelectMembers from '@/views/create_project/selectProjectMembers.vue';
  173. import MenuPage from '@/views/personal_workbench/common/menu.vue';
  174. import UpdateProjectField from './components/UpdateProjectField.vue';
  175. import ProjectMenu from '@/views/project_manage/common/ProjectMenu.vue';
  176. export default {
  177. name: 'ProjectInfoManage',
  178. components: {
  179. SelectMembers,
  180. MenuPage,
  181. UpdateProjectField,
  182. ProjectMenu,
  183. },
  184. data() {
  185. console.log(this.$route.query);
  186. return {
  187. id: this.$route.params.id,
  188. isManage: this.$route.query.isManage === 'true', // 是否为管理模式
  189. backPath: this.$route.query.backPath || '/personal_workbench/project',
  190. labelInput: '',
  191. selectMembersTitle: '',
  192. visibleMembers: false,
  193. type: '',
  194. list: {
  195. leader: [],
  196. member: [],
  197. },
  198. project: {
  199. name: '',
  200. category: '',
  201. label_list: [],
  202. language: '',
  203. topic: '',
  204. publisher: '',
  205. content_intro: '',
  206. background: '',
  207. author_intro: '',
  208. content_count_YG: 100,
  209. word_count_YG: 100000,
  210. plan_publish_date: '', // 计划出版日期
  211. reader: '', // 读者对象
  212. leader_id_list: [], // 组长列表
  213. leader_name_desc: '', // 组长名称描述
  214. member_id_list: [], // 组员列表
  215. member_name_desc: '', // 组员名称描述
  216. creator_name: '', // 创建人名称
  217. create_time: '', // 创建时间
  218. editor: '', // 作者
  219. cover_image_file_id: null, // 封面图片ID
  220. cover_image_file_url: '', // 封面图片URL
  221. },
  222. visibleUpdateField: false,
  223. curField: '',
  224. curFieldValue: '',
  225. };
  226. },
  227. created() {
  228. this.getProjectInfo();
  229. },
  230. methods: {
  231. getProjectInfo() {
  232. GetProjectInfo({ id: this.id }).then(({ project_info, member_list, leader_list }) => {
  233. this.project = project_info;
  234. this.project.leader_name_desc = leader_list.map((user) => user.name).join(',');
  235. this.project.member_name_desc = member_list.map((user) => user.name).join(',');
  236. this.getUserList_ID(project_info.leader_id_list, 'leader');
  237. this.getUserList_ID(project_info.member_id_list, 'member');
  238. });
  239. },
  240. // 处理标签输入
  241. labelChange() {
  242. if (this.labelInput.trim() !== '') {
  243. this.project.label_list.push(this.labelInput.trim());
  244. this.labelInput = ''; // 清空输入框
  245. }
  246. },
  247. selectLeader() {
  248. this.selectMembersTitle = '选择组长';
  249. this.type = 'leader';
  250. this.visibleMembers = true;
  251. },
  252. selectMembers() {
  253. this.selectMembersTitle = '选择项目成员';
  254. this.type = 'member';
  255. this.visibleMembers = true;
  256. },
  257. /**
  258. * 处理选择的成员
  259. * @param {Array} selectedUsers - 选中的用户列表
  260. */
  261. handleSelectedMembers(selectedUsers) {
  262. if (this.type === 'leader') {
  263. this.project.leader_id_list = selectedUsers.map((user) => user.id);
  264. this.setProjectLeader();
  265. } else if (this.type === 'member') {
  266. this.project.member_id_list = selectedUsers.map((user) => user.id);
  267. this.setProjectMember();
  268. }
  269. },
  270. /**
  271. * 得到用户列表(指定ID)
  272. * @param {Array} id_list - 用户ID列表
  273. * @param {string} type - 用户类型(组长或组员)
  274. */
  275. getUserList_ID(id_list, type) {
  276. GetUserList_ID({ id_list }).then(({ user_list }) => {
  277. if (type === 'leader') {
  278. this.list.leader = user_list;
  279. } else if (type === 'member') {
  280. this.list.member = user_list;
  281. }
  282. });
  283. },
  284. // 设置项目成员
  285. setProjectMember() {
  286. SetProjectMember({
  287. project_id: this.id,
  288. user_id_list: this.project.member_id_list,
  289. }).then(() => {
  290. this.$message.success('项目成员更新成功');
  291. this.getProjectInfo();
  292. });
  293. },
  294. // 设置项目组长
  295. setProjectLeader() {
  296. SetProjectLeader({
  297. project_id: this.id,
  298. user_id_list: this.project.leader_id_list,
  299. }).then(() => {
  300. this.$message.success('项目组长更新成功');
  301. this.getProjectInfo();
  302. });
  303. },
  304. /**
  305. * 显示更新字段对话框
  306. * @param {string} field - 字段名称
  307. * @param {any} value - 当前字段值
  308. */
  309. showUpdateField(field, value) {
  310. this.curField = field;
  311. this.curFieldValue = value;
  312. this.visibleUpdateField = true;
  313. },
  314. /**
  315. * 更新项目字段值
  316. * @param {string} field_name - 字段名称
  317. * @param {any} value - 新的字段值
  318. */
  319. updateProjectFieldValue(field_name, value) {
  320. if (field_name === 'label_list') {
  321. SetProjectLabel({
  322. project_id: this.id,
  323. label_list: value,
  324. }).then(() => {
  325. this.$message.success('项目标签更新成功');
  326. this.getProjectInfo();
  327. });
  328. return;
  329. }
  330. UpdateProjectFieldValue({
  331. project_id: this.id,
  332. field_name,
  333. value,
  334. }).then(() => {
  335. this.$message.success('项目更新成功');
  336. this.getProjectInfo();
  337. });
  338. },
  339. },
  340. };
  341. </script>
  342. <style lang="scss" scoped>
  343. @use '@/styles/mixin.scss' as *;
  344. .project-info {
  345. @include page-content(true);
  346. &__header {
  347. .name {
  348. width: 240px;
  349. font-size: 16px;
  350. font-weight: bold;
  351. }
  352. }
  353. &-manage {
  354. row-gap: 0 !important;
  355. max-width: 1148px;
  356. margin: 0 auto !important;
  357. .table-fourcolumn,
  358. .table-twocolumn {
  359. display: grid;
  360. .label,
  361. .project-item {
  362. padding: 4px 8px;
  363. line-height: 32px;
  364. border-bottom: $border;
  365. }
  366. .label {
  367. text-align: right;
  368. background-color: $fill-color;
  369. &.label-list {
  370. display: flex;
  371. flex-direction: column;
  372. row-gap: 18px;
  373. padding: 12px 8px;
  374. }
  375. }
  376. .project-item {
  377. display: flex;
  378. column-gap: 8px;
  379. :first-child {
  380. flex: 1;
  381. }
  382. &.info-list {
  383. flex-direction: column;
  384. padding: 3px 8px;
  385. :first-child {
  386. flex: none;
  387. }
  388. .info-item {
  389. display: flex;
  390. align-items: center;
  391. justify-content: space-between;
  392. height: 50px;
  393. padding: 9px 0;
  394. &:not(:last-child) {
  395. border-bottom: $border;
  396. }
  397. }
  398. }
  399. .cover-image {
  400. display: flex;
  401. align-items: center;
  402. justify-content: center;
  403. width: 373px;
  404. height: 248px;
  405. overflow: hidden;
  406. img {
  407. display: block;
  408. flex: none;
  409. max-width: 373px;
  410. max-height: 248px;
  411. }
  412. }
  413. }
  414. }
  415. .table-fourcolumn:first-child {
  416. grid-template-rows: 40px 258px;
  417. grid-template-columns: 120px 1fr 120px 1fr;
  418. }
  419. .table-fourcolumn:nth-child(3) {
  420. grid-template-rows: repeat(2, minmax(40px, auto));
  421. grid-template-columns: 120px 1fr 120px 1fr;
  422. }
  423. .table-twocolumn {
  424. grid-template-rows: repeat(3, minmax(40px, auto));
  425. grid-template-columns: 120px 1fr;
  426. }
  427. }
  428. }
  429. </style>