Menu.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <template>
  2. <ElMenu class="menu" mode="horizontal" @select="handleSelect">
  3. <ElMenuItem class="menu-logo" index="logo">
  4. SEECODER Developer
  5. </ElMenuItem>
  6. <ElSubmenu index="project">
  7. <template #title>{{selectedProject.name}}</template>
  8. <template v-if="projectList.length > 0">
  9. <ElMenuItem v-for="project in projectList" :key="project.id" :index="`project-${project.id}`">{{project.name}}</ElMenuItem>
  10. </template>
  11. <template v-else>
  12. <ElMenuItem disabled>暂无项目</ElMenuItem>
  13. </template>
  14. </ElSubmenu>
  15. <template v-if="userLoggedIn">
  16. <ElSubmenu index="user" class="user">
  17. <template #title>{{userInfo.username}}</template>
  18. <ElMenuItem index="user-project">创建项目</ElMenuItem>
  19. <ElMenuItem index="user-invite">邀请成员</ElMenuItem>
  20. <ElMenuItem index="user-logout">登出</ElMenuItem>
  21. </ElSubmenu>
  22. </template>
  23. <template v-else>
  24. <ElButton type="text" @click="login" class="user">登录</ElButton>
  25. </template>
  26. </ElMenu>
  27. <ElDrawer v-model="showProjectDrawer">
  28. <template #title><span>创建项目</span></template>
  29. <div class="drawer-content">
  30. <div class="form-container">
  31. <ElForm :model="createProjectForm">
  32. <ElFormItem label="项目名" prop="name">
  33. <ElInput v-model="createProjectForm.name" placeholder="请输入要创建的项目名"></ElInput>
  34. </ElFormItem>
  35. <ElFormItem label="项目描述" prop="description">
  36. <ElInput
  37. v-model="createProjectForm.description"
  38. placeholder="请输入项目描述"
  39. type="textarea"
  40. :autosize="{ minRows: 3, maxRows: 3}"
  41. ></ElInput>
  42. </ElFormItem>
  43. <ElFormItem>
  44. <ElButton @click="createProject" type="primary">创建</ElButton>
  45. </ElFormItem>
  46. </ElForm>
  47. </div>
  48. </div>
  49. </ElDrawer>
  50. <ElDrawer v-model="showInviteDrawer">
  51. <template #title><span>邀请成员</span></template>
  52. <div class="drawer-content">
  53. <div class="form-container">
  54. <ElForm :model="inviteProjectForm">
  55. <ElFormItem label="项目" prop="projectId">
  56. <ElSelect v-model="inviteProjectForm.projectId" placeholder="请选择成员将要加入的项目">
  57. <ElOption v-for="project in projectList" :key="project.id" :value="project.id" :label="project.name"></ElOption>
  58. </ElSelect>
  59. </ElFormItem>
  60. <ElFormItem label="手机号" prop="phone">
  61. <ElInput v-model="inviteProjectForm.phone" placeholder="请输入成员注册所用手机号"></ElInput>
  62. </ElFormItem>
  63. <ElFormItem>
  64. <ElButton @click="inviteMember" type="primary">邀请</ElButton>
  65. </ElFormItem>
  66. </ElForm>
  67. </div>
  68. </div>
  69. </ElDrawer>
  70. </template>
  71. <script lang="ts">
  72. import { ElMessage } from 'element-plus';
  73. import { useProjectList } from '@/composable/useProject';
  74. import { useUser } from '@/composable/useUser';
  75. import { defineComponent, ref, reactive } from 'vue';
  76. import { ProjectAPI } from '@/api';
  77. import { WorkspaceDispatcher } from '@/store/dispatchers';
  78. import { useRouter } from 'vue-router';
  79. export default defineComponent({
  80. name: 'Menu',
  81. setup() {
  82. const { projectList, selectedProject, handleProjectChange } = useProjectList();
  83. const { userInfo, userLoggedIn, userLogOut } = useUser();
  84. const router = useRouter();
  85. const showProjectDrawer = ref(false);
  86. const showInviteDrawer = ref(false);
  87. const openProjectDrawer = () => {
  88. showProjectDrawer.value = true;
  89. };
  90. const openInviteDrawer = () => {
  91. showInviteDrawer.value = true;
  92. };
  93. const createProjectForm = reactive({
  94. name: '',
  95. description: '',
  96. });
  97. const createProject = async () => {
  98. await ProjectAPI.createProject(createProjectForm.name, createProjectForm.description);
  99. showProjectDrawer.value = false;
  100. WorkspaceDispatcher.refreshProjectList();
  101. };
  102. interface InviteProjectForm {
  103. projectId: undefined | number;
  104. phone: string;
  105. }
  106. const inviteProjectForm = reactive<InviteProjectForm>({
  107. projectId: undefined,
  108. phone: '',
  109. });
  110. const inviteMember = async () => {
  111. if (!inviteProjectForm.projectId) {
  112. ElMessage({
  113. type: 'error',
  114. message: '请选择有效的项目',
  115. });
  116. return;
  117. }
  118. await ProjectAPI.addProjectMember({
  119. projectId: inviteProjectForm.projectId,
  120. phone: inviteProjectForm.phone,
  121. });
  122. showInviteDrawer.value = false;
  123. if (selectedProject.value.id !== -1) { WorkspaceDispatcher.changeProject(selectedProject.value.id); }
  124. };
  125. const handleSelect = (index: string) => {
  126. const [type, id] = index.split('-');
  127. switch (type) {
  128. case 'logo': {
  129. router.push('/home');
  130. break;
  131. }
  132. case 'project': {
  133. handleProjectChange(parseInt(id, 10));
  134. break;
  135. }
  136. case 'user': {
  137. if (id === 'project') {
  138. openProjectDrawer();
  139. } else if (id === 'invite') {
  140. openInviteDrawer();
  141. } else if (id === 'logout') {
  142. userLogOut();
  143. }
  144. break;
  145. }
  146. default:
  147. console.warn('unknown type of sub-menu');
  148. break;
  149. }
  150. };
  151. const login = () => {
  152. window.location = `http://${process.env.VUE_APP_PORTAL_HOST}/interaction?scope=openid&client_id=seec-seec&redirect_uri=${
  153. encodeURI(`http://${window.location.host}/`)
  154. }` as unknown as Location;
  155. };
  156. return {
  157. projectList,
  158. selectedProject,
  159. handleSelect,
  160. userInfo,
  161. userLoggedIn,
  162. userLogOut,
  163. showProjectDrawer,
  164. showInviteDrawer,
  165. createProjectForm,
  166. createProject,
  167. inviteProjectForm,
  168. inviteMember,
  169. login,
  170. };
  171. },
  172. });
  173. </script>
  174. <style scoped>
  175. .menu {
  176. width: 100%;
  177. position: fixed;
  178. z-index: 1000;
  179. }
  180. .menu-logo {
  181. color: #000000;
  182. font-size: 24px;
  183. font-weight: bolder;
  184. line-height: 58px;
  185. /*margin-left: 30px;*/
  186. transition: all .2s linear;
  187. user-select: none;
  188. }
  189. .menu-logo.is-disabled {
  190. opacity: 1;
  191. cursor: default;
  192. }
  193. .user {
  194. float: right;
  195. height: 60px;
  196. margin: 0 20px;
  197. }
  198. .drawer-content {
  199. display: flex;
  200. justify-content: center;
  201. }
  202. .form-container {
  203. width: 80%;
  204. }
  205. </style>