1
0

LoginSelect.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <BasicModal v-bind="config" @register="registerModal" :title="currTitle" wrapClassName="loginSelectModal" v-model:visible="visible">
  3. <a-form ref="formRef" :model="formState" :rules="rules" v-bind="layout" :colon="false" class="loginSelectForm">
  4. <!--多租户选择-->
  5. <a-form-item v-if="isMultiTenant" name="tenantId" :validate-status="validate_status">
  6. <!--label内容-->
  7. <template #label>
  8. <a-tooltip placement="topLeft">
  9. <template #title>
  10. <span>您隶属于多租户,请选择登录租户</span>
  11. </template>
  12. <a-avatar style="background-color: #87d068" :size="30"> 租户 </a-avatar>
  13. </a-tooltip>
  14. </template>
  15. <template #extra v-if="validate_status == 'error'">
  16. <span style="color: #ed6f6f">请选择登录租户</span>
  17. </template>
  18. <!--租户下拉内容-->
  19. <a-select
  20. v-model:value="formState.tenantId"
  21. @change="handleTenantChange"
  22. placeholder="请选择登录租户"
  23. :class="{ 'valid-error': validate_status == 'error' }"
  24. >
  25. <template v-for="tenant in tenantList" :key="tenant.id">
  26. <a-select-option :value="tenant.id">{{ tenant.name }}</a-select-option>
  27. </template>
  28. </a-select>
  29. </a-form-item>
  30. <!--多部门选择-->
  31. <a-form-item v-if="isMultiDepart" :validate-status="validate_status1" :colon="false">
  32. <!--label内容-->
  33. <template #label>
  34. <a-tooltip placement="topLeft">
  35. <template #title>
  36. <span>您隶属于多部门,请选择登录部门</span>
  37. </template>
  38. <a-avatar style="background-color: rgb(104, 208, 203)" :size="30"> 部门 </a-avatar>
  39. </a-tooltip>
  40. </template>
  41. <template #extra v-if="validate_status1 == 'error'">
  42. <span style="color: #ed6f6f">请选择登录部门</span>
  43. </template>
  44. <!--部门下拉内容-->
  45. <a-select
  46. v-model:value="formState.orgCode"
  47. @change="handleDepartChange"
  48. placeholder="请选择登录部门"
  49. :class="{ 'valid-error': validate_status1 == 'error' }"
  50. >
  51. <template v-for="depart in departList" :key="depart.orgCode">
  52. <a-select-option :value="depart.orgCode">{{ depart.departName }}</a-select-option>
  53. </template>
  54. </a-select>
  55. </a-form-item>
  56. </a-form>
  57. <template #footer>
  58. <a-button @click="handleSubmit" type="primary">确认</a-button>
  59. </template>
  60. </BasicModal>
  61. </template>
  62. <script lang="ts">
  63. import { defineComponent, ref, computed, watch, unref, reactive, UnwrapRef } from 'vue';
  64. import { Avatar } from 'ant-design-vue';
  65. import { BasicModal, useModalInner } from '/@/components/Modal';
  66. import { useMessage } from '/@/hooks/web/useMessage';
  67. import { useUserStore } from '/@/store/modules/user';
  68. import { defHttp } from '/@/utils/http/axios';
  69. interface FormState {
  70. orgCode: string | undefined;
  71. tenantId: number;
  72. }
  73. export default defineComponent({
  74. name: 'LoginSelect',
  75. components: {
  76. Avatar,
  77. BasicModal,
  78. },
  79. emits: ['success', 'register'],
  80. setup(props, { emit }) {
  81. const userStore = useUserStore();
  82. const { notification } = useMessage();
  83. //租户配置
  84. const isMultiTenant = ref(false);
  85. const tenantList = ref([]);
  86. const validate_status = ref('');
  87. //部门配置
  88. const isMultiDepart = ref(false);
  89. const departList = ref([]);
  90. const validate_status1 = ref('');
  91. //弹窗显隐
  92. const visible = ref(false);
  93. //登录用户
  94. const username = ref('');
  95. //表单
  96. const formRef = ref();
  97. //选择的租户部门信息
  98. const formState: UnwrapRef<FormState> = reactive({
  99. orgCode: undefined,
  100. tenantId: null,
  101. });
  102. const config = {
  103. maskClosable: false,
  104. closable: false,
  105. canFullscreen: false,
  106. width: '500px',
  107. minHeight: 20,
  108. maxHeight: 20,
  109. };
  110. //弹窗操作
  111. const [registerModal, { closeModal }] = useModalInner();
  112. //当前标题
  113. const currTitle = computed(() => {
  114. if (unref(isMultiDepart) && unref(isMultiTenant)) {
  115. return '请选择租户和部门';
  116. } else if (unref(isMultiDepart) && !unref(isMultiTenant)) {
  117. return '请选择部门';
  118. } else if (!unref(isMultiDepart) && unref(isMultiTenant)) {
  119. return '请选择租户';
  120. }
  121. });
  122. const rules = ref({
  123. tenantId: [{ required: unref(isMultiTenant), type: 'number', message: '请选择租户', trigger: 'change' }],
  124. orgCode: [{ required: unref(isMultiDepart), message: '请选择部门', trigger: 'change' }],
  125. });
  126. const layout = {
  127. labelCol: { span: 4 },
  128. wrapperCol: { span: 18 },
  129. };
  130. /**
  131. * 处理部门情况
  132. */
  133. function bizDepart(loginResult) {
  134. let multi_depart = loginResult.multi_depart;
  135. //0:无部门 1:一个部门 2:多个部门
  136. if (multi_depart == 0) {
  137. notification.warn({
  138. message: '提示',
  139. description: `您尚未归属部门,请确认账号信息`,
  140. duration: 3,
  141. });
  142. isMultiDepart.value = false;
  143. } else if (multi_depart == 2) {
  144. isMultiDepart.value = true;
  145. departList.value = loginResult.departs;
  146. } else {
  147. isMultiDepart.value = false;
  148. }
  149. }
  150. /**
  151. * 处理租户情况
  152. */
  153. function bizTenantList(loginResult) {
  154. let tenantArr = loginResult.tenantList;
  155. if (Array.isArray(tenantArr)) {
  156. if (tenantArr.length === 0) {
  157. isMultiTenant.value = false;
  158. userStore.setTenant(formState.tenantId);
  159. } else if (tenantArr.length === 1) {
  160. formState.tenantId = tenantArr[0].id;
  161. isMultiTenant.value = false;
  162. userStore.setTenant(formState.tenantId);
  163. } else {
  164. isMultiTenant.value = true;
  165. tenantList.value = tenantArr;
  166. }
  167. }
  168. }
  169. /**
  170. * 确认选中的租户和部门信息
  171. */
  172. function handleSubmit() {
  173. if (unref(isMultiTenant) && !formState.tenantId) {
  174. validate_status.value = 'error';
  175. return false;
  176. }
  177. if (unref(isMultiDepart) && !formState.orgCode) {
  178. validate_status1.value = 'error';
  179. return false;
  180. }
  181. formRef.value
  182. .validate()
  183. .then(() => {
  184. departResolve()
  185. .then(() => {
  186. userStore.setTenant(formState.tenantId);
  187. emit('success');
  188. })
  189. .catch((e) => {
  190. console.log('登录选择出现问题', e);
  191. })
  192. .finally(() => {
  193. close();
  194. });
  195. })
  196. .catch((err) => {
  197. console.log('表单校验未通过error', err);
  198. });
  199. }
  200. /**
  201. *切换选择部门
  202. */
  203. function departResolve() {
  204. return new Promise((resolve, reject) => {
  205. if (!unref(isMultiDepart)) {
  206. resolve();
  207. } else {
  208. let params = { orgCode: formState.orgCode, username: unref(username) };
  209. defHttp.put({ url: '/sys/selectDepart', params }).then((res) => {
  210. if (res.userInfo) {
  211. userStore.setUserInfo(res.userInfo);
  212. resolve();
  213. } else {
  214. requestFailed(res);
  215. userStore.logout();
  216. reject();
  217. }
  218. });
  219. }
  220. });
  221. }
  222. /**
  223. * 请求失败处理
  224. */
  225. function requestFailed(err) {
  226. notification.error({
  227. message: '登录失败',
  228. description: ((err.response || {}).data || {}).message || err.message || '请求出现错误,请稍后再试',
  229. duration: 4,
  230. });
  231. }
  232. /**
  233. * 关闭model
  234. */
  235. function close() {
  236. closeModal();
  237. reset();
  238. }
  239. /**
  240. * 弹窗打开前处理
  241. */
  242. async function show(loginResult) {
  243. if (loginResult) {
  244. username.value = userStore.username;
  245. await reset();
  246. await bizDepart(loginResult);
  247. await bizTenantList(loginResult);
  248. if (!unref(isMultiDepart) && !unref(isMultiTenant)) {
  249. emit('success', userStore.getUserInfo);
  250. } else {
  251. visible.value = true;
  252. }
  253. }
  254. //登录弹窗完成后,将登录的标识设置成false
  255. loginResult.isLogin = false;
  256. userStore.setLoginInfo(loginResult);
  257. }
  258. /**
  259. *重置数据
  260. */
  261. function reset() {
  262. tenantList.value = [];
  263. validate_status.value = '';
  264. departList.value = [];
  265. validate_status1.value = '';
  266. }
  267. function handleTenantChange(e) {
  268. validate_status.value = '';
  269. }
  270. function handleDepartChange(e) {
  271. validate_status1.value = '';
  272. }
  273. return {
  274. registerModal,
  275. visible,
  276. tenantList,
  277. isMultiTenant,
  278. validate_status,
  279. isMultiDepart,
  280. departList,
  281. validate_status1,
  282. formState,
  283. rules,
  284. layout,
  285. formRef,
  286. currTitle,
  287. config,
  288. handleTenantChange,
  289. handleDepartChange,
  290. show,
  291. handleSubmit,
  292. };
  293. },
  294. });
  295. </script>
  296. <style lang="less" scoped>
  297. .loginSelectForm {
  298. margin-bottom: -20px;
  299. }
  300. .loginSelectModal {
  301. top: 10px;
  302. }
  303. </style>