Commit 5f3f30bc1469a6dedce558ba8bb521594ac6673a

Authored by fengistao
2 parents 901b26d2 f40541a3

Merge branch 'main' into ft-dev

Showing 42 changed files with 620 additions and 354 deletions
@@ -5,4 +5,4 @@ VITE_PORT = 8083 @@ -5,4 +5,4 @@ VITE_PORT = 8083
5 VITE_GLOB_APP_TITLE = Yunteng IOT 5 VITE_GLOB_APP_TITLE = Yunteng IOT
6 6
7 # spa shortname 7 # spa shortname
8 -VITE_GLOB_APP_SHORT_NAME = Yunteng IOT 8 +# VITE_GLOB_APP_SHORT_NAME = Yunteng IOT
@@ -45,7 +45,6 @@ @@ -45,7 +45,6 @@
45 "cropperjs": "^1.5.12", 45 "cropperjs": "^1.5.12",
46 "crypto-js": "^4.1.1", 46 "crypto-js": "^4.1.1",
47 "echarts": "^5.1.2", 47 "echarts": "^5.1.2",
48 - "emit": "^0.0.2",  
49 "intro.js": "^4.1.0", 48 "intro.js": "^4.1.0",
50 "jwt-decode": "^3.1.2", 49 "jwt-decode": "^3.1.2",
51 "lodash-es": "^4.17.21", 50 "lodash-es": "^4.17.21",
  1 +import { defHttp } from '/@/utils/http/axios';
  2 +
  3 +export const getDeviceProfile = () => {
  4 + return defHttp.get({
  5 + url: '/deviceProfile/me',
  6 + });
  7 +};
@@ -90,3 +90,8 @@ export const updateAppDesign = (data) => { @@ -90,3 +90,8 @@ export const updateAppDesign = (data) => {
90 data, 90 data,
91 }); 91 });
92 }; 92 };
  93 +
  94 +// 二维码上传
  95 +export const qrcodeUpload = (file) => {
  96 + return defHttp.post<FileUploadResponse>({ url: API.BaseUploadUrl, params: file });
  97 +};
@@ -2,12 +2,18 @@ @@ -2,12 +2,18 @@
2 * @Author: Vben 2 * @Author: Vben
3 * @Description: logo component 3 * @Description: logo component
4 --> 4 -->
  5 +
5 <template> 6 <template>
6 <div class="anticon" :class="getAppLogoClass" @click="goHome"> 7 <div class="anticon" :class="getAppLogoClass" @click="goHome">
7 - <img src="../../../assets/images/logo.png" />  
8 - <div class="ml-2 md:opacity-100" :class="getTitleClass" v-show="showTitle">  
9 - {{ title }}  
10 - </div> 8 + <img :src="getLogo" />
  9 + <span
  10 + class="ml-2 md:opacity-100"
  11 + :class="getTitleClass"
  12 + v-show="showTitle"
  13 + style="white-space: nowrap"
  14 + >
  15 + {{ getTitle }}
  16 + </span>
11 </div> 17 </div>
12 </template> 18 </template>
13 <script lang="ts" setup> 19 <script lang="ts" setup>
@@ -18,7 +24,6 @@ @@ -18,7 +24,6 @@
18 import { useDesign } from '/@/hooks/web/useDesign'; 24 import { useDesign } from '/@/hooks/web/useDesign';
19 import { PageEnum } from '/@/enums/pageEnum'; 25 import { PageEnum } from '/@/enums/pageEnum';
20 import { useUserStore } from '/@/store/modules/user'; 26 import { useUserStore } from '/@/store/modules/user';
21 -  
22 const props = defineProps({ 27 const props = defineProps({
23 /** 28 /**
24 * The theme of the current parent component 29 * The theme of the current parent component
@@ -45,7 +50,6 @@ @@ -45,7 +50,6 @@
45 props.theme, 50 props.theme,
46 { 'collapsed-show-title': unref(getCollapsedShowTitle) }, 51 { 'collapsed-show-title': unref(getCollapsedShowTitle) },
47 ]); 52 ]);
48 -  
49 const getTitleClass = computed(() => [ 53 const getTitleClass = computed(() => [
50 `${prefixCls}__title`, 54 `${prefixCls}__title`,
51 { 55 {
@@ -56,10 +60,22 @@ @@ -56,10 +60,22 @@
56 function goHome() { 60 function goHome() {
57 go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME); 61 go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
58 } 62 }
  63 + const getLogo = computed(() => {
  64 + return userStore.platInfo?.logo ?? '/src/assets/images/logo.png';
  65 + });
  66 + const getTitle = computed(() => {
  67 + // 设置icon
  68 + let link = (document.querySelector("link[rel*='icon']") ||
  69 + document.createElement('link')) as HTMLLinkElement;
  70 + link.type = 'image/x-icon';
  71 + link.rel = 'shortcut icon';
  72 + link.href = userStore.platInfo?.icon ?? '/public/favicon.ico';
  73 + document.getElementsByTagName('head')[0].appendChild(link);
  74 + return userStore.platInfo?.name ?? title;
  75 + });
59 </script> 76 </script>
60 <style lang="less" scoped> 77 <style lang="less" scoped>
61 @prefix-cls: ~'@{namespace}-app-logo'; 78 @prefix-cls: ~'@{namespace}-app-logo';
62 -  
63 .@{prefix-cls} { 79 .@{prefix-cls} {
64 display: flex; 80 display: flex;
65 align-items: center; 81 align-items: center;
@@ -29,6 +29,7 @@ export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__'; @@ -29,6 +29,7 @@ export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__';
29 // base global session key 29 // base global session key
30 export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY__'; 30 export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY__';
31 31
  32 +export const PLATFORM = 'PLATFORM';
32 export enum CacheTypeEnum { 33 export enum CacheTypeEnum {
33 SESSION, 34 SESSION,
34 LOCAL, 35 LOCAL,
1 export enum RoleEnum { 1 export enum RoleEnum {
2 - ROLE_SYS_ADMIN = 'ROLE_SYS_ADMIN',  
3 - ROLE_TENANT_ADMIN = 'ROLE_TENANT_ADMIN',  
4 - ROLE_NORMAL_USER = 'ROLE_NORMAL_USER',  
5 - ROLE_PLATFORM_ADMIN = 'ROLE_PLATFORM_ADMIN', 2 + ROLE_SYS_ADMIN = 'SYS_ADMIN',
  3 + ROLE_TENANT_ADMIN = 'TENANT_ADMIN',
  4 + ROLE_NORMAL_USER = 'CUSTOMER_USER',
  5 + ROLE_PLATFORM_ADMIN = 'PLATFORM_ADMIN',
6 } 6 }
@@ -25,8 +25,10 @@ import { router } from '/@/router'; @@ -25,8 +25,10 @@ import { router } from '/@/router';
25 import { usePermissionStore } from '/@/store/modules/permission'; 25 import { usePermissionStore } from '/@/store/modules/permission';
26 import { RouteRecordRaw } from 'vue-router'; 26 import { RouteRecordRaw } from 'vue-router';
27 import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; 27 import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
28 - 28 +import { createLocalStorage } from '/@/utils/cache/index';
29 interface UserState { 29 interface UserState {
  30 + platInfo: any;
  31 + enterPriseInfo: any;
30 userInfo: Nullable<UserInfo>; 32 userInfo: Nullable<UserInfo>;
31 token?: string; 33 token?: string;
32 roleList: RoleEnum[]; 34 roleList: RoleEnum[];
@@ -36,9 +38,13 @@ interface UserState { @@ -36,9 +38,13 @@ interface UserState {
36 refreshToken?: string; 38 refreshToken?: string;
37 } 39 }
38 40
  41 +const storage = createLocalStorage();
39 export const useUserStore = defineStore({ 42 export const useUserStore = defineStore({
40 id: 'app-user', 43 id: 'app-user',
41 state: (): UserState => ({ 44 state: (): UserState => ({
  45 + //平台信息
  46 + platInfo: storage.get('platInfo') || null,
  47 + enterPriseInfo: storage.get('enterPriseInfo') || null,
42 // user info 48 // user info
43 userInfo: null, 49 userInfo: null,
44 // token 50 // token
@@ -52,7 +58,11 @@ export const useUserStore = defineStore({ @@ -52,7 +58,11 @@ export const useUserStore = defineStore({
52 // Last fetch time 58 // Last fetch time
53 lastUpdateTime: 0, 59 lastUpdateTime: 0,
54 }), 60 }),
  61 +
55 getters: { 62 getters: {
  63 + getPlatInfo(): any {
  64 + return this.platInfo;
  65 + },
56 getUserInfo(): UserInfo { 66 getUserInfo(): UserInfo {
57 return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {}; 67 return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
58 }, 68 },
@@ -73,6 +83,12 @@ export const useUserStore = defineStore({ @@ -73,6 +83,12 @@ export const useUserStore = defineStore({
73 }, 83 },
74 }, 84 },
75 actions: { 85 actions: {
  86 + setPlatInfo(platInfo: any) {
  87 + this.platInfo = platInfo;
  88 + },
  89 + setEnterPriseInfo(enterPriseInfo: any) {
  90 + this.enterPriseInfo = enterPriseInfo;
  91 + },
76 storeToken(jwtToken: string, refreshToken: string) { 92 storeToken(jwtToken: string, refreshToken: string) {
77 this.jwtToken = jwtToken; 93 this.jwtToken = jwtToken;
78 this.refreshToken = refreshToken; 94 this.refreshToken = refreshToken;
@@ -5,6 +5,7 @@ import type { RouteLocationNormalized } from 'vue-router'; @@ -5,6 +5,7 @@ import type { RouteLocationNormalized } from 'vue-router';
5 import { createLocalStorage, createSessionStorage } from '/@/utils/cache'; 5 import { createLocalStorage, createSessionStorage } from '/@/utils/cache';
6 import { Memory } from './memory'; 6 import { Memory } from './memory';
7 import { 7 import {
  8 + PLATFORM,
8 TOKEN_KEY, 9 TOKEN_KEY,
9 JWT_TOKEN_KEY, 10 JWT_TOKEN_KEY,
10 REFRESH_TOKEN_KEY, 11 REFRESH_TOKEN_KEY,
@@ -21,6 +22,7 @@ import { toRaw } from 'vue'; @@ -21,6 +22,7 @@ import { toRaw } from 'vue';
21 import { pick, omit } from 'lodash-es'; 22 import { pick, omit } from 'lodash-es';
22 23
23 interface BasicStore { 24 interface BasicStore {
  25 + [PLATFORM]: Object;
24 [TOKEN_KEY]: string | number | null | undefined; 26 [TOKEN_KEY]: string | number | null | undefined;
25 [JWT_TOKEN_KEY]: string | number | null | undefined; 27 [JWT_TOKEN_KEY]: string | number | null | undefined;
26 [REFRESH_TOKEN_KEY]: string | number | null | undefined; 28 [REFRESH_TOKEN_KEY]: string | number | null | undefined;
1 -import { BasicColumn } from '/@/components/Table';  
2 -  
3 -import { FormSchema } from '/@/components/Table'; 1 +import type { BasicColumn } from '/@/components/Table';
  2 +import type { FormSchema } from '/@/components/Table';
  3 +import { getOrganizationList } from '/@/api/system/system';
  4 +import { copyTransFun } from '/@/utils/fnUtils';
  5 +import { getDeviceProfile } from '/@/api/alarm/position';
4 export const formSchema: FormSchema[] = [ 6 export const formSchema: FormSchema[] = [
5 { 7 {
6 - field: 'organization', 8 + field: 'organizationId',
7 label: '', 9 label: '',
8 - component: 'TreeSelect', 10 + component: 'ApiTreeSelect',
9 componentProps: { 11 componentProps: {
10 - placeholder: '请选择组织', 12 + api: async () => {
  13 + const data = await getOrganizationList();
  14 + copyTransFun(data as any as any[]);
  15 + return data;
  16 + },
11 }, 17 },
12 }, 18 },
13 { 19 {
14 - field: 'organization', 20 + field: 'profileId',
15 label: '', 21 label: '',
16 - component: 'Select', 22 + component: 'ApiSelect',
17 componentProps: { 23 componentProps: {
  24 + api: getDeviceProfile,
18 placeholder: '请选择设备配置', 25 placeholder: '请选择设备配置',
  26 + labelField: 'name',
  27 + valueField: 'id',
19 }, 28 },
20 }, 29 },
21 { 30 {
22 - field: 'device', 31 + field: 'name',
23 label: '', 32 label: '',
24 component: 'Input', 33 component: 'Input',
25 componentProps: { 34 componentProps: {
@@ -27,19 +36,28 @@ export const formSchema: FormSchema[] = [ @@ -27,19 +36,28 @@ export const formSchema: FormSchema[] = [
27 }, 36 },
28 }, 37 },
29 { 38 {
30 - field: 'status', 39 + field: 'deviceState',
31 label: '', 40 label: '',
32 component: 'RadioGroup', 41 component: 'RadioGroup',
33 componentProps: { 42 componentProps: {
34 size: 'small', 43 size: 'small',
35 options: [ 44 options: [
36 - { label: '全部', value: 'Apple' },  
37 - { label: '离线', value: 'Pear' },  
38 - { label: '在线', value: 'Orange' }, 45 + { label: '待激活', value: 'INACTIVE' },
  46 + { label: '在线', value: 'ONLINE' },
  47 + { label: '离线', value: 'OFFLINE' },
39 { label: '报警', value: 'hhh' }, 48 { label: '报警', value: 'hhh' },
40 ], 49 ],
41 }, 50 },
42 }, 51 },
  52 + {
  53 + field: 'alarmStatus',
  54 + label: '',
  55 + component: 'RadioGroup',
  56 + componentProps: {
  57 + size: 'small',
  58 + options: [{ label: '是否报警', value: '' }],
  59 + },
  60 + },
43 ]; 61 ];
44 62
45 export const columns: BasicColumn[] = [ 63 export const columns: BasicColumn[] = [
@@ -57,5 +75,6 @@ export const columns: BasicColumn[] = [ @@ -57,5 +75,6 @@ export const columns: BasicColumn[] = [
57 title: '状态', 75 title: '状态',
58 dataIndex: 'deviceState', 76 dataIndex: 'deviceState',
59 width: 100, 77 width: 100,
  78 + slots: { customRender: 'deviceState' },
60 }, 79 },
61 ]; 80 ];
@@ -2,7 +2,28 @@ @@ -2,7 +2,28 @@
2 <div class="wrapper"> 2 <div class="wrapper">
3 <div ref="wrapRef" :style="{ height, width }"> </div> 3 <div ref="wrapRef" :style="{ height, width }"> </div>
4 <div class="right-wrap"> 4 <div class="right-wrap">
5 - <BasicTable @register="registerTable" /> 5 + <BasicTable @register="registerTable">
  6 + <template #deviceState="{ record }">
  7 + <Tag
  8 + :color="
  9 + record.deviceState == DeviceState.INACTIVE
  10 + ? 'warning'
  11 + : record.deviceState == DeviceState.ONLINE
  12 + ? 'success'
  13 + : 'error'
  14 + "
  15 + class="ml-2"
  16 + >
  17 + {{
  18 + record.deviceState == DeviceState.INACTIVE
  19 + ? '待激活'
  20 + : record.deviceState == DeviceState.ONLINE
  21 + ? '在线'
  22 + : '离线'
  23 + }}
  24 + </Tag>
  25 + </template></BasicTable
  26 + >
6 </div> 27 </div>
7 </div> 28 </div>
8 </template> 29 </template>
@@ -12,11 +33,13 @@ @@ -12,11 +33,13 @@
12 import { formSchema, columns } from './config.data'; 33 import { formSchema, columns } from './config.data';
13 import { BasicTable, useTable } from '/@/components/Table'; 34 import { BasicTable, useTable } from '/@/components/Table';
14 import { devicePage } from '/@/api/alarm/contact/alarmContact'; 35 import { devicePage } from '/@/api/alarm/contact/alarmContact';
15 - 36 + import { Tag } from 'ant-design-vue';
  37 + import { DeviceState } from '/@/api/device/model/deviceModel';
16 export default defineComponent({ 38 export default defineComponent({
17 name: 'BaiduMap', 39 name: 'BaiduMap',
18 components: { 40 components: {
19 BasicTable, 41 BasicTable,
  42 + Tag,
20 }, 43 },
21 props: { 44 props: {
22 width: { 45 width: {
@@ -55,8 +78,6 @@ @@ -55,8 +78,6 @@
55 formConfig: { 78 formConfig: {
56 labelWidth: 120, 79 labelWidth: 120,
57 schemas: formSchema, 80 schemas: formSchema,
58 - showAdvancedButton: false,  
59 - showActionButtonGroup: false,  
60 }, 81 },
61 showIndexColumn: false, 82 showIndexColumn: false,
62 useSearchForm: true, 83 useSearchForm: true,
@@ -68,6 +89,7 @@ @@ -68,6 +89,7 @@
68 wrapRef, 89 wrapRef,
69 registerTable, 90 registerTable,
70 handleSuccess, 91 handleSuccess,
  92 + DeviceState,
71 }; 93 };
72 }, 94 },
73 }); 95 });
@@ -83,12 +105,10 @@ @@ -83,12 +105,10 @@
83 .right-wrap { 105 .right-wrap {
84 padding-top: 10px; 106 padding-top: 10px;
85 width: 22%; 107 width: 22%;
86 - height: 80%; 108 + height: 95%;
87 position: absolute; 109 position: absolute;
88 right: 5%; 110 right: 5%;
89 - top: 10%;  
90 - }  
91 - .scroll-wrap {  
92 - height: 450px; 111 + top: 3%;
  112 + background-color: #fff;
93 } 113 }
94 </style> 114 </style>
@@ -132,10 +132,6 @@ export const formSchema: FormSchema[] = [ @@ -132,10 +132,6 @@ export const formSchema: FormSchema[] = [
132 field: 'id', 132 field: 'id',
133 label: '', 133 label: '',
134 component: 'Input', 134 component: 'Input',
135 - componentProps: {  
136 - style: {  
137 - display: 'none',  
138 - },  
139 - }, 135 + show: false,
140 }, 136 },
141 ]; 137 ];
src/views/dashboard/analysis/components/DynamicInfo.vue renamed from src/views/dashboard/workbench/components/DynamicInfo.vue
src/views/dashboard/analysis/components/ProjectCard.vue renamed from src/views/dashboard/workbench/components/ProjectCard.vue
src/views/dashboard/analysis/components/QuickNav.vue renamed from src/views/dashboard/workbench/components/QuickNav.vue
src/views/dashboard/analysis/components/SaleRadar.vue renamed from src/views/dashboard/workbench/components/SaleRadar.vue
src/views/dashboard/analysis/components/WorkbenchHeader.vue renamed from src/views/dashboard/workbench/components/WorkbenchHeader.vue
src/views/dashboard/analysis/components/data.ts renamed from src/views/dashboard/workbench/components/data.ts
1 <template> 1 <template>
2 - <div class="p-4 md:flex">  
3 - <div class="md:w-7/10 w-full !mr-4 enter-y">  
4 - <GrowCard :loading="loading" class="enter-y" />  
5 - <SiteAnalysis class="!my-4 enter-y" :loading="loading" />  
6 - <div class="md:flex enter-y">  
7 - <Card title="核心流程指南" style="width: 100%">  
8 - <img alt="核心流程指南" src="../../../assets/images/flow.png" /> 2 + <PageWrapper>
  3 + <template #headerContent> <WorkbenchHeader /> </template>
  4 + <div class="lg:flex">
  5 + <div class="lg:w-7/10 w-full !mr-4 enter-y">
  6 + <ProjectCard :loading="loading" class="enter-y" />
  7 + <DynamicInfo :loading="loading" class="!my-4 enter-y" />
  8 + </div>
  9 + <div class="lg:w-3/10 w-full enter-y">
  10 + <QuickNav :loading="loading" class="enter-y" />
  11 +
  12 + <Card class="!my-4 enter-y" :loading="loading">
  13 + <img class="xl:h-50 h-30 mx-auto" src="../../../assets/svg/illustration.svg" />
9 </Card> 14 </Card>
  15 +
  16 + <SaleRadar :loading="loading" class="enter-y" />
10 </div> 17 </div>
11 </div> 18 </div>
12 - <div class="md:w-3/10 w-full enter-y">  
13 - <HelpDoc />  
14 - </div>  
15 - </div> 19 + <BasicModal
  20 + @register="register"
  21 + v-bind="$attrs"
  22 + :mask="true"
  23 + :showCancelBtn="false"
  24 + :showOkBtn="false"
  25 + :canFullscreen="false"
  26 + :closable="false"
  27 + :maskStyle="maskColor"
  28 + :height="600"
  29 + :width="1500"
  30 + :maskClosable="false"
  31 + title="请修改密码"
  32 + :helpMessage="['请您修改密码']"
  33 + >
  34 + <PasswordDialog />
  35 + </BasicModal>
  36 + </PageWrapper>
16 </template> 37 </template>
17 <script lang="ts" setup> 38 <script lang="ts" setup>
18 - import { ref } from 'vue';  
19 - import GrowCard from './components/GrowCard.vue';  
20 - import SiteAnalysis from './components/SiteAnalysis.vue'; 39 + import PasswordDialog from '/@/views/system/password/index.vue';
  40 + import { BasicModal, useModal } from '/@/components/Modal';
  41 + import { getAuthCache } from '/@/utils/auth';
  42 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
  43 + import { ref, onMounted } from 'vue';
21 import { Card } from 'ant-design-vue'; 44 import { Card } from 'ant-design-vue';
22 - import HelpDoc from './components/HelpDoc.vue';  
23 - const loading = ref(true); 45 + import { PageWrapper } from '/@/components/Page';
  46 + import WorkbenchHeader from './components/WorkbenchHeader.vue';
  47 + import ProjectCard from './components/ProjectCard.vue';
  48 + import QuickNav from './components/QuickNav.vue';
  49 + import DynamicInfo from './components/DynamicInfo.vue';
  50 + import SaleRadar from './components/SaleRadar.vue';
  51 +
  52 + const maskColor = ref({ backgroundColor: 'grey' });
  53 + const statusModel = ref(false);
  54 + const [register, { openModal }] = useModal();
  55 + onMounted(() => {
  56 + const userInfo: object = getAuthCache(USER_INFO_KEY);
  57 + if (userInfo.needSetPwd == true) {
  58 + statusModel.value = true;
  59 + openModal(statusModel.value);
  60 + } else if (userInfo.needSetPwd == false) {
  61 + openModal(statusModel.value);
  62 + }
  63 + });
  64 + //Yunteng123456!!!
  65 + //Password123456!
  66 + //System123456!
  67 + //Testrole123456!
  68 + const loading = ref(false);
24 setTimeout(() => { 69 setTimeout(() => {
25 loading.value = false; 70 loading.value = false;
26 }, 1500); 71 }, 1500);
src/views/dashboard/workbench/components/GrowCard.vue renamed from src/views/dashboard/analysis/components/GrowCard.vue
src/views/dashboard/workbench/components/HelpDoc.vue renamed from src/views/dashboard/analysis/components/HelpDoc.vue
@@ -34,13 +34,13 @@ @@ -34,13 +34,13 @@
34 </Card> 34 </Card>
35 <Card hoverable title="联系我们" :bordered="false"> 35 <Card hoverable title="联系我们" :bordered="false">
36 <template #cover> 36 <template #cover>
37 - <QrCode :value="qrCodeUrl" class="flex justify-center" /> 37 + <img :src="getQrCode" alt="" style="width: 150px; height: 150px; margin: 50px auto" />
38 </template> 38 </template>
39 <CardMeta> 39 <CardMeta>
40 <template #description> 40 <template #description>
41 - <p>联系人: 张三</p>  
42 - <p>联系电话: 15912341234</p>  
43 - <p>联系地址: 四川省成都市剑南大道北段中1533号 </p> 41 + <p>联系人: {{ getContacts }}</p>
  42 + <p>联系电话: {{ getTel }}</p>
  43 + <p>联系地址: {{ getAddress }} </p>
44 </template> 44 </template>
45 </CardMeta> 45 </CardMeta>
46 </Card> 46 </Card>
@@ -48,9 +48,10 @@ @@ -48,9 +48,10 @@
48 </template> 48 </template>
49 49
50 <script lang="ts"> 50 <script lang="ts">
51 - import { defineComponent, ref } from 'vue'; 51 + import { defineComponent, ref, computed, onMounted } from 'vue';
52 import { Card, AnchorLink, List, ListItem, ListItemMeta, Avatar, CardMeta } from 'ant-design-vue'; 52 import { Card, AnchorLink, List, ListItem, ListItemMeta, Avatar, CardMeta } from 'ant-design-vue';
53 - import { QrCode } from '/@/components/Qrcode/index'; 53 + import { useUserStore } from '/@/store/modules/user';
  54 + import { getEnterPriseDetail } from '/@/api/oem';
54 export default defineComponent({ 55 export default defineComponent({
55 components: { 56 components: {
56 Card, 57 Card,
@@ -60,9 +61,12 @@ @@ -60,9 +61,12 @@
60 ListItemMeta, 61 ListItemMeta,
61 Avatar, 62 Avatar,
62 CardMeta, 63 CardMeta,
63 - QrCode,  
64 }, 64 },
65 setup() { 65 setup() {
  66 + onMounted(async () => {
  67 + const res = await getEnterPriseDetail();
  68 + userStore.setEnterPriseInfo(res);
  69 + });
66 const helpDoc = ref([ 70 const helpDoc = ref([
67 { 71 {
68 title: '如何接入设备?', 72 title: '如何接入设备?',
@@ -137,7 +141,19 @@ @@ -137,7 +141,19 @@
137 }, 141 },
138 ]; 142 ];
139 143
140 - const qrCodeUrl = 'https://www.vvbin.cn'; 144 + const userStore = useUserStore();
  145 + const getContacts = computed(() => {
  146 + return userStore.enterPriseInfo?.contacts;
  147 + });
  148 + const getAddress = computed(() => {
  149 + return userStore.enterPriseInfo?.address;
  150 + });
  151 + const getTel = computed(() => {
  152 + return userStore.enterPriseInfo?.tel;
  153 + });
  154 + const getQrCode = computed(() => {
  155 + return userStore.enterPriseInfo?.qrCode;
  156 + });
141 157
142 return { 158 return {
143 activeKey, 159 activeKey,
@@ -145,7 +161,10 @@ @@ -145,7 +161,10 @@
145 onTabChange, 161 onTabChange,
146 data, 162 data,
147 helpDoc, 163 helpDoc,
148 - qrCodeUrl, 164 + getQrCode,
  165 + getContacts,
  166 + getAddress,
  167 + getTel,
149 }; 168 };
150 }, 169 },
151 }); 170 });
src/views/dashboard/workbench/components/SiteAnalysis.vue renamed from src/views/dashboard/analysis/components/SiteAnalysis.vue
src/views/dashboard/workbench/components/VisitAnalysis.vue renamed from src/views/dashboard/analysis/components/VisitAnalysis.vue
src/views/dashboard/workbench/components/VisitAnalysisBar.vue renamed from src/views/dashboard/analysis/components/VisitAnalysisBar.vue
src/views/dashboard/workbench/components/props.ts renamed from src/views/dashboard/analysis/components/props.ts
src/views/dashboard/workbench/data.ts renamed from src/views/dashboard/analysis/data.ts
1 <template> 1 <template>
2 - <PageWrapper>  
3 - <template #headerContent> <WorkbenchHeader /> </template>  
4 - <div class="lg:flex">  
5 - <div class="lg:w-7/10 w-full !mr-4 enter-y">  
6 - <ProjectCard :loading="loading" class="enter-y" />  
7 - <DynamicInfo :loading="loading" class="!my-4 enter-y" />  
8 - </div>  
9 - <div class="lg:w-3/10 w-full enter-y">  
10 - <QuickNav :loading="loading" class="enter-y" />  
11 -  
12 - <Card class="!my-4 enter-y" :loading="loading">  
13 - <img class="xl:h-50 h-30 mx-auto" src="../../../assets/svg/illustration.svg" /> 2 + <div class="p-4 md:flex">
  3 + <div class="md:w-7/10 w-full !mr-4 enter-y">
  4 + <GrowCard :loading="loading" class="enter-y" />
  5 + <SiteAnalysis class="!my-4 enter-y" :loading="loading" />
  6 + <div class="md:flex enter-y">
  7 + <Card title="核心流程指南" style="width: 100%">
  8 + <img alt="核心流程指南" src="../../../assets/images/flow.png" />
14 </Card> 9 </Card>
15 -  
16 - <SaleRadar :loading="loading" class="enter-y" />  
17 </div> 10 </div>
18 </div> 11 </div>
19 - <BasicModal  
20 - @register="register"  
21 - v-bind="$attrs"  
22 - :mask="true"  
23 - :showCancelBtn="false"  
24 - :showOkBtn="false"  
25 - :canFullscreen="false"  
26 - :closable="false"  
27 - :maskStyle="maskColor"  
28 - :height="600"  
29 - :width="1500"  
30 - :maskClosable="false"  
31 - title="请修改密码"  
32 - :helpMessage="['请您修改密码']"  
33 - >  
34 - <PasswordDialog />  
35 - </BasicModal>  
36 - </PageWrapper> 12 + <div class="md:w-3/10 w-full enter-y">
  13 + <HelpDoc />
  14 + </div>
  15 + </div>
37 </template> 16 </template>
38 <script lang="ts" setup> 17 <script lang="ts" setup>
39 - import PasswordDialog from '/@/views/system/password/index.vue';  
40 - import { BasicModal, useModal } from '/@/components/Modal';  
41 - import { getAuthCache } from '/@/utils/auth';  
42 - import { USER_INFO_KEY } from '/@/enums/cacheEnum';  
43 - import { ref, onMounted } from 'vue'; 18 + import { ref } from 'vue';
  19 + import GrowCard from './components/GrowCard.vue';
  20 + import SiteAnalysis from './components/SiteAnalysis.vue';
44 import { Card } from 'ant-design-vue'; 21 import { Card } from 'ant-design-vue';
45 - import { PageWrapper } from '/@/components/Page';  
46 - import WorkbenchHeader from './components/WorkbenchHeader.vue';  
47 - import ProjectCard from './components/ProjectCard.vue';  
48 - import QuickNav from './components/QuickNav.vue';  
49 - import DynamicInfo from './components/DynamicInfo.vue';  
50 - import SaleRadar from './components/SaleRadar.vue';  
51 -  
52 - const maskColor = ref({ backgroundColor: 'grey' });  
53 - const statusModel = ref(false);  
54 - const [register, { openModal }] = useModal();  
55 - onMounted(() => {  
56 - const userInfo: object = getAuthCache(USER_INFO_KEY);  
57 - if (userInfo.needSetPwd == true) {  
58 - statusModel.value = true;  
59 - openModal(statusModel.value);  
60 - } else if (userInfo.needSetPwd == false) {  
61 - openModal(statusModel.value);  
62 - }  
63 - });  
64 - //Yunteng123456!!!  
65 - //Password123456!  
66 - //System123456!  
67 - //Testrole123456!  
68 - const loading = ref(false); 22 + import HelpDoc from './components/HelpDoc.vue';
  23 + const loading = ref(true);
69 setTimeout(() => { 24 setTimeout(() => {
70 loading.value = false; 25 loading.value = false;
71 }, 1500); 26 }, 1500);
@@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
51 props: { 51 props: {
52 userData: { type: Object }, 52 userData: { type: Object },
53 }, 53 },
54 - emits: ['reload'], 54 + emits: ['reload', 'register'],
55 setup(_, { emit }) { 55 setup(_, { emit }) {
56 const DeviceStep1Ref = ref<InstanceType<typeof DeviceStep1>>(); 56 const DeviceStep1Ref = ref<InstanceType<typeof DeviceStep1>>();
57 const DeviceStep2Ref = ref<InstanceType<typeof DeviceStep2>>(); 57 const DeviceStep2Ref = ref<InstanceType<typeof DeviceStep2>>();
@@ -140,7 +140,7 @@ @@ -140,7 +140,7 @@
140 } 140 }
141 141
142 function goLogin() { 142 function goLogin() {
143 - userStore.logout(true); 143 + userStore.logout();
144 lockStore.resetLockInfo(); 144 lockStore.resetLockInfo();
145 } 145 }
146 146
1 <template> 1 <template>
2 - <div :class="prefixCls" class="relative w-full h-full px-4">  
3 - <AppLocalePicker  
4 - class="absolute text-white top-4 right-4 enter-x xl:text-gray-600"  
5 - :showText="false"  
6 - v-if="!sessionTimeout && showLocale"  
7 - />  
8 - <AppDarkModeToggle class="absolute top-3 right-7 enter-x" v-if="!sessionTimeout" />  
9 -  
10 - <span class="-enter-x xl:hidden">  
11 - <AppLogo :alwaysShowTitle="true" />  
12 - </span>  
13 -  
14 - <div class="container relative h-full py-2 mx-auto sm:px-10">  
15 - <div class="flex h-full">  
16 - <div class="hidden min-h-full pl-4 mr-4 xl:flex xl:flex-col xl:w-6/12">  
17 - <AppLogo class="-enter-x" />  
18 - <div class="my-auto">  
19 - <img :alt="title" src="../../../assets/images/iot.png" class="w-4/5 -mt-16 -enter-x" />  
20 - <div class="mt-10 font-medium text-white -enter-x">  
21 - <span class="inline-block mt-4 text-3xl"> {{ t('sys.login.signInTitle') }}</span>  
22 - </div>  
23 - <div class="mt-5 font-normal text-white text-md dark:text-gray-500 -enter-x">  
24 - {{ t('sys.login.signInDesc') }}  
25 - </div>  
26 - </div>  
27 - </div>  
28 - <div class="flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12">  
29 - <div  
30 - :class="`${prefixCls}-form`"  
31 - class="  
32 - relative  
33 - w-full  
34 - px-5  
35 - py-8  
36 - mx-auto  
37 - my-auto  
38 - rounded-md  
39 - shadow-md  
40 - xl:ml-16 xl:bg-transparent  
41 - sm:px-8  
42 - xl:p-4 xl:shadow-none  
43 - sm:w-3/4  
44 - lg:w-2/4  
45 - xl:w-auto  
46 - enter-x  
47 - "  
48 - >  
49 - <LoginForm />  
50 - <ForgetPasswordForm />  
51 - <RegisterForm />  
52 - <MobileForm />  
53 - <QrCodeForm />  
54 - </div> 2 + <div class="login-page">
  3 + <div class="login-header" :style="{ backgroundColor: isDark ? '#1d3794' : '#22283a' }">
  4 + <AppLogo
  5 + :alwaysShowTitle="true"
  6 + style="z-index: 99; position: absolute; width: 40px; height: 100px; left: 10%; top: -20px"
  7 + />
  8 + <AppLocalePicker
  9 + class="absolute text-white top-4 right-4 enter-x xl:text-gray-600"
  10 + :showText="false"
  11 + v-if="!sessionTimeout && showLocale"
  12 + />
  13 + <AppDarkModeToggle
  14 + class="absolute top-3 right-7 enter-x"
  15 + v-if="!sessionTimeout"
  16 + @click="toggleDark"
  17 + />
  18 + </div>
  19 + <div class="login-container" :class="{ light1: isDark, dark: !isDark }">
  20 + <div class="login-description">
  21 + <h1>物联网平台</h1>
  22 + <h2>输入您的个人详细信息开始使用!</h2>
  23 + </div>
  24 + <div class="flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12">
  25 + <div
  26 + :class="`${prefixCls}-form`"
  27 + class="
  28 + relative
  29 + w-full
  30 + px-5
  31 + py-8
  32 + mx-auto
  33 + my-auto
  34 + rounded-md
  35 + shadow-md
  36 + xl:ml-16 xl:bg-transparent
  37 + sm:px-8
  38 + xl:p-4 xl:shadow-none
  39 + sm:w-3/4
  40 + lg:w-2/4
  41 + xl:w-auto
  42 + enter-x
  43 + "
  44 + :style="{ backgroundColor: isDark ? '#fff' : '#1a2030' }"
  45 + >
  46 + <LoginForm />
  47 + <ForgetPasswordForm />
  48 + <RegisterForm />
  49 + <MobileForm />
  50 + <QrCodeForm />
55 </div> 51 </div>
56 </div> 52 </div>
  53 + <div style="position: absolute; bottom: 20px; left: 45%">{{ getCopyRight }}</div>
57 </div> 54 </div>
58 </div> 55 </div>
59 </template> 56 </template>
60 <script lang="ts" setup> 57 <script lang="ts" setup>
61 - import { computed } from 'vue'; 58 + import { computed, ref } from 'vue';
62 import { AppLogo } from '/@/components/Application'; 59 import { AppLogo } from '/@/components/Application';
63 import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application'; 60 import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application';
64 import LoginForm from './LoginForm.vue'; 61 import LoginForm from './LoginForm.vue';
@@ -70,6 +67,7 @@ @@ -70,6 +67,7 @@
70 import { useI18n } from '/@/hooks/web/useI18n'; 67 import { useI18n } from '/@/hooks/web/useI18n';
71 import { useDesign } from '/@/hooks/web/useDesign'; 68 import { useDesign } from '/@/hooks/web/useDesign';
72 import { useLocaleStore } from '/@/store/modules/locale'; 69 import { useLocaleStore } from '/@/store/modules/locale';
  70 + import { useUserStore } from '/@/store/modules/user';
73 71
74 defineProps({ 72 defineProps({
75 sessionTimeout: { 73 sessionTimeout: {
@@ -83,145 +81,69 @@ @@ -83,145 +81,69 @@
83 const localeStore = useLocaleStore(); 81 const localeStore = useLocaleStore();
84 const showLocale = localeStore.getShowPicker; 82 const showLocale = localeStore.getShowPicker;
85 const title = computed(() => globSetting?.title ?? ''); 83 const title = computed(() => globSetting?.title ?? '');
  84 + const isDark = ref(true);
  85 + const toggleDark = () => {
  86 + isDark.value = !isDark.value;
  87 + };
  88 + const userStore = useUserStore();
  89 + const getCopyRight = computed(() => {
  90 + return (userStore.platInfo?.copyright ?? '') + (userStore.platInfo?.presentedOurselves ?? '');
  91 + });
86 </script> 92 </script>
87 <style lang="less"> 93 <style lang="less">
88 @prefix-cls: ~'@{namespace}-login'; 94 @prefix-cls: ~'@{namespace}-login';
89 @logo-prefix-cls: ~'@{namespace}-app-logo'; 95 @logo-prefix-cls: ~'@{namespace}-app-logo';
90 @countdown-prefix-cls: ~'@{namespace}-countdown-input'; 96 @countdown-prefix-cls: ~'@{namespace}-countdown-input';
91 @dark-bg: #293146; 97 @dark-bg: #293146;
92 -  
93 - html[data-theme='dark'] {  
94 - .@{prefix-cls} {  
95 - background-color: @dark-bg;  
96 -  
97 - &::before {  
98 - background-image: url(/@/assets/svg/login-bg-dark.svg);  
99 - }  
100 -  
101 - .ant-input,  
102 - .ant-input-password {  
103 - background-color: #232a3b;  
104 - }  
105 -  
106 - .ant-btn:not(.ant-btn-link):not(.ant-btn-primary) {  
107 - border: 1px solid #4a5569;  
108 - }  
109 -  
110 - &-form {  
111 - background: transparent !important;  
112 - }  
113 -  
114 - .app-iconify {  
115 - color: #fff;  
116 - }  
117 - }  
118 -  
119 - input.fix-auto-fill,  
120 - .fix-auto-fill input {  
121 - -webkit-text-fill-color: #c9d1d9 !important;  
122 - box-shadow: inherit !important;  
123 - } 98 + .light1 {
  99 + background-image: url('/src/assets/images/bg.png');
124 } 100 }
125 -  
126 - .@{prefix-cls} {  
127 - min-height: 100%;  
128 - overflow: hidden;  
129 - @media (max-width: @screen-xl) {  
130 - background-color: #293146;  
131 -  
132 - .@{prefix-cls}-form {  
133 - background-color: #fff;  
134 - }  
135 - }  
136 -  
137 - &::before {  
138 - position: absolute;  
139 - top: 0;  
140 - left: 0; 101 + .dark {
  102 + background-image: url('/src/assets/images/bg-dark.png');
  103 + }
  104 + .login-page {
  105 + width: 100%;
  106 + height: 100%;
  107 + position: relative;
  108 + .login-header {
  109 + height: 60px;
141 width: 100%; 110 width: 100%;
142 - height: 100%;  
143 - margin-left: -48%;  
144 - background-image: url(/@/assets/svg/login-bg.svg);  
145 - background-position: 100%;  
146 - background-repeat: no-repeat;  
147 - background-size: auto 100%;  
148 - content: '';  
149 - @media (max-width: @screen-xl) {  
150 - display: none; 111 + background-color: #1d3794;
  112 + .vben-dark-switch {
  113 + margin-left: 1840px;
151 } 114 }
152 } 115 }
153 116
154 - .@{logo-prefix-cls} {  
155 - position: absolute;  
156 - top: 12px;  
157 - height: 30px;  
158 -  
159 - &__title {  
160 - font-size: 16px;  
161 - color: #fff;  
162 - } 117 + .login-container {
  118 + position: relative;
  119 + left: -6px;
  120 + right: 20px;
  121 + width: 101vw;
  122 + height: calc(100% - 60px);
  123 + background-size: 100% 100%;
  124 + background-repeat: no-repeat;
  125 + .vben-login-form {
  126 + position: absolute;
163 127
164 - img {  
165 - width: 32px; 128 + width: 410px;
  129 + right: 200px;
  130 + top: 50%;
  131 + margin-top: -180px;
166 } 132 }
167 - }  
168 -  
169 - .container {  
170 - .@{logo-prefix-cls} {  
171 - display: flex;  
172 - width: 60%;  
173 - height: 80px;  
174 -  
175 - &__title {  
176 - font-size: 24px;  
177 - color: #fff; 133 + .login-description {
  134 + position: absolute;
  135 + right: 13%;
  136 + top: 15%;
  137 + h1 {
  138 + font-size: 26px;
  139 + color: #5aeeed;
  140 + text-align: center;
178 } 141 }
179 -  
180 - img {  
181 - width: 48px; 142 + h2 {
  143 + font-size: 20px;
  144 + color: #5aeeed;
182 } 145 }
183 } 146 }
184 } 147 }
185 -  
186 - &-sign-in-way {  
187 - .anticon {  
188 - font-size: 22px;  
189 - color: #888;  
190 - cursor: pointer;  
191 -  
192 - &:hover {  
193 - color: @primary-color;  
194 - }  
195 - }  
196 - }  
197 -  
198 - input:not([type='checkbox']) {  
199 - min-width: 360px;  
200 -  
201 - @media (max-width: @screen-xl) {  
202 - min-width: 320px;  
203 - }  
204 -  
205 - @media (max-width: @screen-lg) {  
206 - min-width: 260px;  
207 - }  
208 -  
209 - @media (max-width: @screen-md) {  
210 - min-width: 240px;  
211 - }  
212 -  
213 - @media (max-width: @screen-sm) {  
214 - min-width: 160px;  
215 - }  
216 - }  
217 -  
218 - .@{countdown-prefix-cls} input {  
219 - min-width: unset;  
220 - }  
221 -  
222 - .ant-divider-inner-text {  
223 - font-size: 12px;  
224 - color: @text-color-secondary;  
225 - }  
226 } 148 }
227 </style> 149 </style>
@@ -44,7 +44,7 @@ @@ -44,7 +44,7 @@
44 </ARow> 44 </ARow>
45 <ARow class="enter-x"> 45 <ARow class="enter-x">
46 <ACol :span="12"> 46 <ACol :span="12">
47 - <FormItem> </FormItem> 47 + <FormItem />
48 </ACol> 48 </ACol>
49 <ACol :span="12"> 49 <ACol :span="12">
50 <FormItem :style="{ 'text-align': 'right' }"> 50 <FormItem :style="{ 'text-align': 'right' }">
@@ -60,7 +60,7 @@ @@ -60,7 +60,7 @@
60 <script lang="ts" setup> 60 <script lang="ts" setup>
61 import { reactive, ref, toRaw, unref, computed } from 'vue'; 61 import { reactive, ref, toRaw, unref, computed } from 'vue';
62 62
63 - import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue'; 63 + import { Form, Input, Row, Col, Button } from 'ant-design-vue';
64 import LoginFormTitle from './LoginFormTitle.vue'; 64 import LoginFormTitle from './LoginFormTitle.vue';
65 65
66 import { useI18n } from '/@/hooks/web/useI18n'; 66 import { useI18n } from '/@/hooks/web/useI18n';
@@ -69,7 +69,8 @@ @@ -69,7 +69,8 @@
69 import { useUserStore } from '/@/store/modules/user'; 69 import { useUserStore } from '/@/store/modules/user';
70 import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin'; 70 import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
71 import { useDesign } from '/@/hooks/web/useDesign'; 71 import { useDesign } from '/@/hooks/web/useDesign';
72 - //import { onKeyStroke } from '@vueuse/core'; 72 + import { getPlatForm } from '/@/api/oem/index';
  73 + import { createLocalStorage } from '/@/utils/cache/index';
73 74
74 const ACol = Col; 75 const ACol = Col;
75 const ARow = Row; 76 const ARow = Row;
@@ -78,14 +79,12 @@ @@ -78,14 +79,12 @@
78 const { t } = useI18n(); 79 const { t } = useI18n();
79 const { notification, createErrorModal } = useMessage(); 80 const { notification, createErrorModal } = useMessage();
80 const { prefixCls } = useDesign('login'); 81 const { prefixCls } = useDesign('login');
81 - const userStore = useUserStore();  
82 82
83 const { setLoginState, getLoginState } = useLoginState(); 83 const { setLoginState, getLoginState } = useLoginState();
84 const { getFormRules } = useFormRules(); 84 const { getFormRules } = useFormRules();
85 - 85 + const userStore = useUserStore();
86 const formRef = ref(); 86 const formRef = ref();
87 const loading = ref(false); 87 const loading = ref(false);
88 - const rememberMe = ref(false);  
89 88
90 const formData = reactive({ 89 const formData = reactive({
91 account: 'sysadmin', 90 account: 'sysadmin',
@@ -116,8 +115,11 @@ @@ -116,8 +115,11 @@
116 description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`, 115 description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,
117 duration: 3, 116 duration: 3,
118 }); 117 });
  118 + const res = await getPlatForm();
  119 + const storage = createLocalStorage();
  120 + storage.set('platformInfo', res);
119 } 121 }
120 - } catch (error) { 122 + } catch (error: any) {
121 createErrorModal({ 123 createErrorModal({
122 title: t('sys.api.loginFailed'), 124 title: t('sys.api.loginFailed'),
123 content: 125 content:
@@ -131,5 +133,15 @@ @@ -131,5 +133,15 @@
131 } finally { 133 } finally {
132 loading.value = false; 134 loading.value = false;
133 } 135 }
  136 +
  137 + const res = await getPlatForm();
  138 + userStore.setPlatInfo(res);
  139 + // 设置icon
  140 + let link = (document.querySelector("link[rel*='icon']") ||
  141 + document.createElement('link')) as HTMLLinkElement;
  142 + link.type = 'image/x-icon';
  143 + link.rel = 'shortcut icon';
  144 + link.href = res.icon ?? '/public/favicon.ico';
  145 + document.getElementsByTagName('head')[0].appendChild(link);
134 } 146 }
135 </script> 147 </script>
1 <template> 1 <template>
2 - <h2 class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-left"> 2 + <h2
  3 + class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-left flex justify-center"
  4 + >
3 {{ getFormTitle }} 5 {{ getFormTitle }}
4 </h2> 6 </h2>
5 </template> 7 </template>
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <div class="enter-x min-w-64 min-h-64"> 4 <div class="enter-x min-w-64 min-h-64">
5 <QrCode 5 <QrCode
6 :value="qrCodeUrl" 6 :value="qrCodeUrl"
7 - class="enter-x flex justify-center xl:justify-start" 7 + class="enter-x flex justify-center xl:justify-center"
8 :width="280" 8 :width="280"
9 /> 9 />
10 <Divider class="enter-x">{{ t('sys.login.scanSign') }}</Divider> 10 <Divider class="enter-x">{{ t('sys.login.scanSign') }}</Divider>
@@ -52,7 +52,7 @@ @@ -52,7 +52,7 @@
52 import MenuDrawer from './MenuDrawer.vue'; 52 import MenuDrawer from './MenuDrawer.vue';
53 53
54 // 导入列 属性,和搜索栏内容 54 // 导入列 属性,和搜索栏内容
55 - import { columns, searchFormSchema } from './menu.data'; 55 + import { columns } from './menu.data';
56 import { useI18n } from '/@/hooks/web/useI18n'; 56 import { useI18n } from '/@/hooks/web/useI18n';
57 import { notification } from 'ant-design-vue'; 57 import { notification } from 'ant-design-vue';
58 58
@@ -65,7 +65,6 @@ @@ -65,7 +65,6 @@
65 const { t } = useI18n(); //加载国际化 65 const { t } = useI18n(); //加载国际化
66 // 新增菜单 66 // 新增菜单
67 const getI18nCreateMenu = computed(() => t('routes.common.system.pageSystemTitleCreateMenu')); 67 const getI18nCreateMenu = computed(() => t('routes.common.system.pageSystemTitleCreateMenu'));
68 - console.log(111);  
69 const [registerTable, { reload, expandAll }] = useTable({ 68 const [registerTable, { reload, expandAll }] = useTable({
70 title: t('routes.common.system.pageSystemTitleMenuList'), //'菜单列表' 69 title: t('routes.common.system.pageSystemTitleMenuList'), //'菜单列表'
71 api: getMenuList, //加载数据 70 api: getMenuList, //加载数据
@@ -98,10 +98,11 @@ @@ -98,10 +98,11 @@
98 const { createMessage } = useMessage(); 98 const { createMessage } = useMessage();
99 const [tenantAdminFormDrawer, { openDrawer: openTenantAdminFormDrawer }] = useDrawer(); 99 const [tenantAdminFormDrawer, { openDrawer: openTenantAdminFormDrawer }] = useDrawer();
100 100
  101 + const tenantId = ref('');
101 function handleCreateTenantAdmin() { 102 function handleCreateTenantAdmin() {
102 openTenantAdminFormDrawer(true, { 103 openTenantAdminFormDrawer(true, {
103 isUpdate: false, 104 isUpdate: false,
104 - tenantCode: tenantCode, 105 + tenantId: tenantId.value,
105 }); 106 });
106 } 107 }
107 108
@@ -109,7 +110,7 @@ @@ -109,7 +110,7 @@
109 openTenantAdminFormDrawer(true, { 110 openTenantAdminFormDrawer(true, {
110 isUpdate: true, 111 isUpdate: true,
111 record, 112 record,
112 - tenantCode: tenantCode, 113 + tenantCode: tenantId.value,
113 }); 114 });
114 } 115 }
115 116
@@ -160,7 +161,6 @@ @@ -160,7 +161,6 @@
160 slots: { customRender: 'status' }, 161 slots: { customRender: 'status' },
161 }, 162 },
162 ]; 163 ];
163 - const tenantCode = ref('');  
164 const [tenantAdminTable, { reload }] = useTable({ 164 const [tenantAdminTable, { reload }] = useTable({
165 api: getTenantAdminPage, 165 api: getTenantAdminPage,
166 columns: tenantAdminColumns as BasicColumn[], 166 columns: tenantAdminColumns as BasicColumn[],
@@ -168,7 +168,7 @@ @@ -168,7 +168,7 @@
168 bordered: true, 168 bordered: true,
169 showIndexColumn: false, 169 showIndexColumn: false,
170 searchInfo: { 170 searchInfo: {
171 - tenantCode: tenantCode, 171 + tenantId: tenantId,
172 roleType: RoleEnum.ROLE_TENANT_ADMIN, 172 roleType: RoleEnum.ROLE_TENANT_ADMIN,
173 }, 173 },
174 actionColumn: { 174 actionColumn: {
@@ -186,8 +186,8 @@ @@ -186,8 +186,8 @@
186 }); 186 });
187 //默认传递页面数据 187 //默认传递页面数据
188 const [tenantAdminDrawer, { closeDrawer }] = useDrawerInner(async (data) => { 188 const [tenantAdminDrawer, { closeDrawer }] = useDrawerInner(async (data) => {
189 - tenantCode.value = data.record.tenantCode;  
190 - await reload(); 189 + tenantId.value = data.record.tenantId;
  190 + reload();
191 }); 191 });
192 192
193 //提交按钮 193 //提交按钮
@@ -204,7 +204,7 @@ @@ -204,7 +204,7 @@
204 handleCreateTenantAdmin, 204 handleCreateTenantAdmin,
205 handleSubmit, 205 handleSubmit,
206 tenantAdminTable, 206 tenantAdminTable,
207 - tenantCode, 207 + tenantId,
208 tenantAdminFormDrawer, 208 tenantAdminFormDrawer,
209 handleSuccess, 209 handleSuccess,
210 handleEdit, 210 handleEdit,
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 width="60%" 7 width="60%"
8 @ok="handleSubmit" 8 @ok="handleSubmit"
9 > 9 >
10 - <BasicForm @register="tenantAdminForm"> </BasicForm> 10 + <BasicForm @register="tenantAdminForm" />
11 </BasicDrawer> 11 </BasicDrawer>
12 </template> 12 </template>
13 <script lang="ts"> 13 <script lang="ts">
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 }, 25 },
26 setup(_, { emit }) { 26 setup(_, { emit }) {
27 const isUpdate = ref(true); 27 const isUpdate = ref(true);
28 - const tenantCode = ref(''); 28 + const tenantId = ref('');
29 const formSchema: FormSchema[] = [ 29 const formSchema: FormSchema[] = [
30 { 30 {
31 field: 'id', 31 field: 'id',
@@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
81 async (data) => { 81 async (data) => {
82 await resetFields(); 82 await resetFields();
83 isUpdate.value = !!data?.isUpdate; 83 isUpdate.value = !!data?.isUpdate;
84 - tenantCode.value = data?.tenantCode; 84 + tenantId.value = data?.tenantId;
85 await updateSchema({ field: 'title', componentProps: { disabled: false } }); 85 await updateSchema({ field: 'title', componentProps: { disabled: false } });
86 if (unref(isUpdate)) { 86 if (unref(isUpdate)) {
87 await setFieldsValue({ 87 await setFieldsValue({
@@ -106,7 +106,7 @@ @@ -106,7 +106,7 @@
106 typeof values.tenantExpireTime != 'undefined' && values.tenantExpireTime != null 106 typeof values.tenantExpireTime != 'undefined' && values.tenantExpireTime != null
107 ? values.tenantExpireTime.format('YYYY-MM-DD HH:mm:ss') 107 ? values.tenantExpireTime.format('YYYY-MM-DD HH:mm:ss')
108 : null, 108 : null,
109 - tenantCode: tenantCode.value, 109 + tenantId: tenantId.value,
110 }; 110 };
111 setDrawerProps({ confirmLoading: true }); 111 setDrawerProps({ confirmLoading: true });
112 saveTenantAdmin(requestParams as any as UserDTO).then(() => { 112 saveTenantAdmin(requestParams as any as UserDTO).then(() => {
@@ -35,8 +35,8 @@ @@ -35,8 +35,8 @@
35 :before-upload="beforeUploadIconPic" 35 :before-upload="beforeUploadIconPic"
36 > 36 >
37 <div v-if="iconPic"> 37 <div v-if="iconPic">
38 - <img :src="iconPic" />  
39 - <div style="background-color: #ccc">重新上传</div> 38 + <img :src="iconPic" class="m-auto" />
  39 + <div style="background-color: #ccc; margin-top: 20px">重新上传</div>
40 </div> 40 </div>
41 <div v-else> 41 <div v-else>
42 <PlusOutlined style="font-size: 30px" /> 42 <PlusOutlined style="font-size: 30px" />
@@ -95,6 +95,8 @@ @@ -95,6 +95,8 @@
95 import type { FileItem } from '/@/components/Upload/src/typing'; 95 import type { FileItem } from '/@/components/Upload/src/typing';
96 import { logoUpload, iconUpload, bgUpload, getPlatForm, updatePlatForm } from '/@/api/oem/index'; 96 import { logoUpload, iconUpload, bgUpload, getPlatForm, updatePlatForm } from '/@/api/oem/index';
97 import { PlusOutlined } from '@ant-design/icons-vue'; 97 import { PlusOutlined } from '@ant-design/icons-vue';
  98 + import { useUserStore } from '/@/store/modules/user';
  99 + import { createLocalStorage } from '/@/utils/cache/index';
98 export default defineComponent({ 100 export default defineComponent({
99 components: { 101 components: {
100 BasicForm, 102 BasicForm,
@@ -111,6 +113,8 @@ @@ -111,6 +113,8 @@
111 tip: '拼命加载中...', 113 tip: '拼命加载中...',
112 }); 114 });
113 const { createMessage } = useMessage(); 115 const { createMessage } = useMessage();
  116 + const userStore = useUserStore();
  117 + const storage = createLocalStorage();
114 const [registerForm, { getFieldsValue, setFieldsValue }] = useForm({ 118 const [registerForm, { getFieldsValue, setFieldsValue }] = useForm({
115 schemas, 119 schemas,
116 showSubmitButton: false, 120 showSubmitButton: false,
@@ -146,7 +150,7 @@ @@ -146,7 +150,7 @@
146 } 150 }
147 return isJpgOrPng && isLt2M; 151 return isJpgOrPng && isLt2M;
148 }; 152 };
149 - 153 + // Icon上传
150 async function customUploadIconPic({ file }) { 154 async function customUploadIconPic({ file }) {
151 if (beforeUploadIconPic(file)) { 155 if (beforeUploadIconPic(file)) {
152 const formData = new FormData(); 156 const formData = new FormData();
@@ -158,9 +162,9 @@ @@ -158,9 +162,9 @@
158 } 162 }
159 } 163 }
160 const beforeUploadIconPic = (file: FileItem) => { 164 const beforeUploadIconPic = (file: FileItem) => {
161 - const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; 165 + const isJpgOrPng = file.type === 'image/x-icon';
162 if (!isJpgOrPng) { 166 if (!isJpgOrPng) {
163 - createMessage.error('只能上传图片文件!'); 167 + createMessage.error('只能上传.icon图片文件!');
164 } 168 }
165 const isLt2M = (file.size as number) / 1024 < 500; 169 const isLt2M = (file.size as number) / 1024 < 500;
166 if (!isLt2M) { 170 if (!isLt2M) {
@@ -196,18 +200,28 @@ @@ -196,18 +200,28 @@
196 try { 200 try {
197 const fieldValue = getFieldsValue(); 201 const fieldValue = getFieldsValue();
198 compState.value.loading = true; 202 compState.value.loading = true;
199 - await updatePlatForm({ 203 + const newFieldValue = {
200 ...fieldValue, 204 ...fieldValue,
201 - background: unref(bgPic),  
202 - icon: unref(bgPic),  
203 logo: unref(logoPic), 205 logo: unref(logoPic),
204 - }); 206 + icon: unref(iconPic),
  207 + background: unref(bgPic),
  208 + };
  209 + await updatePlatForm(newFieldValue);
205 compState.value.loading = false; 210 compState.value.loading = false;
206 createMessage.success('保存信息成功'); 211 createMessage.success('保存信息成功');
  212 +
  213 + setPlatFormInfo(newFieldValue);
207 } catch (e) { 214 } catch (e) {
208 createMessage.error('保存信息失败'); 215 createMessage.error('保存信息失败');
209 } 216 }
210 }; 217 };
  218 + // 设置平台信息
  219 + function setPlatFormInfo(newFieldValue) {
  220 + // 保存store
  221 + userStore.setPlatInfo(newFieldValue);
  222 + // 保存本地缓存
  223 + storage.set('platInfo', newFieldValue);
  224 + }
211 225
212 onMounted(async () => { 226 onMounted(async () => {
213 const res = await getPlatForm(); 227 const res = await getPlatForm();
1 <template> 1 <template>
2 <div class="card"> 2 <div class="card">
3 - <Card :bordered="false" class="card"> <BasicForm @register="registerForm" /></Card> 3 + <Card :bordered="false" class="card">
  4 + <BasicForm @register="registerForm">
  5 + <template #qrcode>
  6 + <Upload
  7 + name="avatar"
  8 + list-type="picture-card"
  9 + class="avatar-uploader"
  10 + :show-upload-list="false"
  11 + :customRequest="customUploadqrcodePic"
  12 + :before-upload="beforeUploadqrcodePic"
  13 + >
  14 + <img v-if="qrcodePic" :src="qrcodePic" alt="avatar" />
  15 + <div v-else>
  16 + <div style="margin-top: 30px">
  17 + <PlusOutlined style="font-size: 30px" />
  18 + </div>
  19 + <div
  20 + class="ant-upload-text flex"
  21 + style="width: 280px; height: 130px; align-items: center"
  22 + >
  23 + 支持.PNG、.JPG、.SVG格式,建议尺寸为300px × 300px(及以上),大小不超过2M。</div
  24 + >
  25 + </div>
  26 + </Upload>
  27 + </template></BasicForm
  28 + ></Card
  29 + >
4 <Loading v-bind="compState" /> 30 <Loading v-bind="compState" />
5 <a-button 31 <a-button
6 @click="handleUpdateInfo" 32 @click="handleUpdateInfo"
@@ -14,17 +40,25 @@ @@ -14,17 +40,25 @@
14 40
15 <script lang="ts"> 41 <script lang="ts">
16 import { defineComponent, onMounted, ref } from 'vue'; 42 import { defineComponent, onMounted, ref } from 'vue';
17 - import { Card } from 'ant-design-vue'; 43 + import { Card, Upload } from 'ant-design-vue';
18 import { BasicForm, useForm } from '/@/components/Form/index'; 44 import { BasicForm, useForm } from '/@/components/Form/index';
19 import { schemas } from '../config/enterPriseInfo.config'; 45 import { schemas } from '../config/enterPriseInfo.config';
20 import { getEnterPriseDetail, updateEnterPriseDetail } from '/@/api/oem/index'; 46 import { getEnterPriseDetail, updateEnterPriseDetail } from '/@/api/oem/index';
21 import { Loading } from '/@/components/Loading'; 47 import { Loading } from '/@/components/Loading';
22 import { useMessage } from '/@/hooks/web/useMessage'; 48 import { useMessage } from '/@/hooks/web/useMessage';
  49 + import { getTownChild } from '/@/api/oem/index';
  50 + import { useUserStore } from '/@/store/modules/user';
  51 + import { createLocalStorage } from '/@/utils/cache';
  52 + import { PlusOutlined } from '@ant-design/icons-vue';
  53 + import type { FileItem } from '/@/components/Upload/src/typing';
  54 + import { qrcodeUpload } from '/@/api/oem/index';
23 export default defineComponent({ 55 export default defineComponent({
24 components: { 56 components: {
25 Card, 57 Card,
26 BasicForm, 58 BasicForm,
27 Loading, 59 Loading,
  60 + Upload,
  61 + PlusOutlined,
28 }, 62 },
29 setup() { 63 setup() {
30 const compState = ref({ 64 const compState = ref({
@@ -32,7 +66,7 @@ @@ -32,7 +66,7 @@
32 loading: false, 66 loading: false,
33 tip: '拼命加载中...', 67 tip: '拼命加载中...',
34 }); 68 });
35 - const [registerForm, { getFieldsValue, setFieldsValue }] = useForm({ 69 + const [registerForm, { getFieldsValue, setFieldsValue, updateSchema }] = useForm({
36 labelWidth: 80, 70 labelWidth: 80,
37 schemas, 71 schemas,
38 showResetButton: false, 72 showResetButton: false,
@@ -42,32 +76,204 @@ @@ -42,32 +76,204 @@
42 }, 76 },
43 }); 77 });
44 const { createMessage } = useMessage(); 78 const { createMessage } = useMessage();
  79 +
  80 + const qrcodePic = ref();
  81 + const customUploadqrcodePic = async ({ file }) => {
  82 + if (beforeUploadqrcodePic(file)) {
  83 + const formData = new FormData();
  84 + formData.append('file', file);
  85 + const response = await qrcodeUpload(formData);
  86 + if (response.fileStaticUri) {
  87 + qrcodePic.value = response.fileStaticUri;
  88 + }
  89 + }
  90 + };
  91 + const beforeUploadqrcodePic = (file: FileItem) => {
  92 + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  93 + if (!isJpgOrPng) {
  94 + createMessage.error('只能上传图片文件!');
  95 + }
  96 + const isLt2M = (file.size as number) / 1024 / 1024 < 2;
  97 + if (!isLt2M) {
  98 + createMessage.error('图片大小不能超过2MB!');
  99 + }
  100 + return isJpgOrPng && isLt2M;
  101 + };
  102 + // 更新
45 const handleUpdateInfo = async () => { 103 const handleUpdateInfo = async () => {
46 try { 104 try {
47 compState.value.loading = true; 105 compState.value.loading = true;
48 const fieldsValue = getFieldsValue(); 106 const fieldsValue = getFieldsValue();
49 - await updateEnterPriseDetail({ 107 + const newFieldValue = {
50 ...fieldsValue, 108 ...fieldsValue,
51 codeProv: fieldsValue.nameProv, 109 codeProv: fieldsValue.nameProv,
52 codeCity: fieldsValue.nameCity, 110 codeCity: fieldsValue.nameCity,
53 codeCoun: fieldsValue.nameCoun, 111 codeCoun: fieldsValue.nameCoun,
54 codeTown: fieldsValue.nameTown, 112 codeTown: fieldsValue.nameTown,
55 - }); 113 + qrCode: qrcodePic.value,
  114 + };
  115 + console.log(fieldsValue);
  116 + console.log(newFieldValue);
  117 + await updateEnterPriseDetail(newFieldValue);
56 compState.value.loading = false; 118 compState.value.loading = false;
57 createMessage.success('更新信息成功'); 119 createMessage.success('更新信息成功');
  120 + setEnterPriseInfo(newFieldValue);
58 } catch (e) { 121 } catch (e) {
59 createMessage.error('更新信息失败'); 122 createMessage.error('更新信息失败');
60 } 123 }
61 }; 124 };
  125 +
  126 + const userStore = useUserStore();
  127 + const storage = createLocalStorage();
  128 +
  129 + // 设置企业信息
  130 + function setEnterPriseInfo(newFieldValue) {
  131 + // 保存store
  132 + userStore.setEnterPriseInfo(newFieldValue);
  133 + // 保存本地缓存
  134 + storage.set('enterpriseInfo', newFieldValue);
  135 + }
  136 +
  137 + // 地区显示回显和数据联动
  138 + async function updateCityData(
  139 + codeProv: string,
  140 + codeCity: string,
  141 + codeCoun: string,
  142 + codeTown: string
  143 + ) {
  144 + const nameCity = await getTownChild('codeProv', codeProv);
  145 + const nameCoun = await getTownChild('codeCity', codeCity);
  146 + const nameTown = await getTownChild('codeCoun', codeCoun);
  147 + nameCity.forEach((item) => {
  148 + item.label = item.nameCity;
  149 + item.value = item.codeCity;
  150 + });
  151 + nameCoun.forEach((item) => {
  152 + item.label = item.nameCoun;
  153 + item.value = item.codeCoun;
  154 + });
  155 + nameTown.forEach((item) => {
  156 + item.label = item.nameTown;
  157 + item.value = item.codeTown;
  158 + });
  159 + setFieldsValue({
  160 + nameProv: codeProv,
  161 + nameCity: codeCity,
  162 + nameCoun: codeCoun,
  163 + nameTown: codeTown,
  164 + });
  165 + updateSchema({
  166 + field: 'nameTown',
  167 + componentProps: {
  168 + options: nameTown,
  169 + },
  170 + });
  171 + updateSchema({
  172 + field: 'nameCoun',
  173 + componentProps: {
  174 + options: nameCoun,
  175 + async onChange(value) {
  176 + if (value === undefined) {
  177 + setFieldsValue({
  178 + nameTown: undefined,
  179 + });
  180 + updateSchema({
  181 + field: 'nameTown',
  182 + componentProps: {
  183 + options: [],
  184 + },
  185 + });
  186 + }
  187 + let nameTown = await getTownChild('codeCoun', value);
  188 + nameTown.forEach((item) => {
  189 + item.label = item.nameTown;
  190 + item.value = item.codeTown;
  191 + });
  192 + setFieldsValue({
  193 + nameTown: undefined,
  194 + });
  195 + updateSchema({
  196 + field: 'nameTown',
  197 + componentProps: {
  198 + placeholder: '请选择街道/城镇',
  199 + options: nameTown,
  200 + },
  201 + });
  202 + },
  203 + },
  204 + });
  205 + updateSchema({
  206 + field: 'nameCity',
  207 + componentProps: ({ formModel }) => {
  208 + return {
  209 + options: nameCity,
  210 + onChange: async (value) => {
  211 + let nameCoun = await getTownChild('codeCity', value);
  212 + if (value === undefined) {
  213 + formModel.nameCoun = undefined; // reset city value
  214 + formModel.nameTown = undefined;
  215 + nameCoun = [];
  216 + updateSchema({
  217 + field: 'nameTown',
  218 + componentProps: {
  219 + options: [],
  220 + },
  221 + });
  222 + }
  223 + nameCoun.forEach((item) => {
  224 + item.label = item.nameCoun;
  225 + item.value = item.codeCoun;
  226 + });
  227 + formModel.nameCoun = undefined; // reset city value
  228 + formModel.nameTown = undefined;
  229 + updateSchema({
  230 + field: 'nameCoun',
  231 + componentProps: {
  232 + // 请选择区
  233 + options: nameCoun,
  234 + async onChange(value) {
  235 + let nameTown = await getTownChild('codeCoun', value);
  236 + if (value === undefined) {
  237 + formModel.nameTown = undefined;
  238 + nameTown = [];
  239 + }
  240 + nameTown.forEach((item) => {
  241 + item.label = item.nameTown;
  242 + item.value = item.codeTown;
  243 + });
  244 +
  245 + formModel.nameTown = undefined;
  246 + updateSchema({
  247 + field: 'nameTown',
  248 + componentProps: {
  249 + placeholder: '请选择街道/城镇',
  250 + options: nameTown,
  251 + },
  252 + });
  253 + },
  254 + },
  255 + });
  256 + },
  257 + };
  258 + },
  259 + });
  260 + }
  261 +
62 onMounted(async () => { 262 onMounted(async () => {
63 const res = await getEnterPriseDetail(); 263 const res = await getEnterPriseDetail();
  264 + updateCityData(res.codeProv, res.codeCity, res.codeCoun, res.codeTown);
64 setFieldsValue(res); 265 setFieldsValue(res);
  266 + qrcodePic.value = res.qrCode;
  267 + console.log(res);
65 }); 268 });
66 269
67 return { 270 return {
68 registerForm, 271 registerForm,
69 compState, 272 compState,
  273 + qrcodePic,
70 handleUpdateInfo, 274 handleUpdateInfo,
  275 + customUploadqrcodePic,
  276 + beforeUploadqrcodePic,
71 }; 277 };
72 }, 278 },
73 }); 279 });
@@ -51,6 +51,7 @@ export const schemas: FormSchema[] = [ @@ -51,6 +51,7 @@ export const schemas: FormSchema[] = [
51 field: 'synopsis', 51 field: 'synopsis',
52 component: 'InputTextArea', 52 component: 'InputTextArea',
53 label: '公司简介', 53 label: '公司简介',
  54 +
54 colProps: { 55 colProps: {
55 span: 24, 56 span: 24,
56 }, 57 },
@@ -116,6 +117,9 @@ export const schemas: FormSchema[] = [ @@ -116,6 +117,9 @@ export const schemas: FormSchema[] = [
116 }, 117 },
117 }); 118 });
118 } 119 }
  120 + formModel.nameCity = undefined; // reset city value
  121 + formModel.nameCoun = undefined;
  122 + formModel.nameTown = undefined;
119 updateSchema({ 123 updateSchema({
120 field: 'nameCity', 124 field: 'nameCity',
121 componentProps: () => { 125 componentProps: () => {
@@ -146,14 +150,20 @@ export const schemas: FormSchema[] = [ @@ -146,14 +150,20 @@ export const schemas: FormSchema[] = [
146 // 请选择区 150 // 请选择区
147 options: nameCoun, 151 options: nameCoun,
148 async onChange(value) { 152 async onChange(value) {
149 - let nameTown = await getTownChild('codeCoun', value); 153 + const nameTown = await getTownChild('codeCoun', value);
150 nameTown.forEach((item) => { 154 nameTown.forEach((item) => {
151 item.label = item.nameTown; 155 item.label = item.nameTown;
152 item.value = item.codeTown; 156 item.value = item.codeTown;
153 }); 157 });
154 if (value === undefined) { 158 if (value === undefined) {
155 formModel.nameTown = undefined; 159 formModel.nameTown = undefined;
156 - nameTown = []; 160 + updateSchema({
  161 + field: 'nameTown',
  162 + componentProps: {
  163 + placeholder: '请选择街道/城镇',
  164 + options: [],
  165 + },
  166 + });
157 } 167 }
158 updateSchema({ 168 updateSchema({
159 field: 'nameTown', 169 field: 'nameTown',
@@ -177,11 +187,10 @@ export const schemas: FormSchema[] = [ @@ -177,11 +187,10 @@ export const schemas: FormSchema[] = [
177 field: 'nameCity', 187 field: 'nameCity',
178 component: 'Select', 188 component: 'Select',
179 label: '', 189 label: '',
180 -  
181 colProps: { 190 colProps: {
182 span: 5, 191 span: 5,
183 style: { 192 style: {
184 - marginLeft: '-80px', 193 + marginLeft: '-5rem',
185 }, 194 },
186 }, 195 },
187 }, 196 },
@@ -213,13 +222,6 @@ export const schemas: FormSchema[] = [ @@ -213,13 +222,6 @@ export const schemas: FormSchema[] = [
213 placeholder: '请选择街道/城镇', 222 placeholder: '请选择街道/城镇',
214 }, 223 },
215 }, 224 },
216 -  
217 - // {  
218 - // field: 'nameProv',  
219 - // label: '所在城市',  
220 - // component: 'Cascader',  
221 - // },  
222 -  
223 { 225 {
224 field: 'address', 226 field: 'address',
225 component: 'Input', 227 component: 'Input',
@@ -254,4 +256,13 @@ export const schemas: FormSchema[] = [ @@ -254,4 +256,13 @@ export const schemas: FormSchema[] = [
254 placeholder: '请输入联系电话', 256 placeholder: '请输入联系电话',
255 }, 257 },
256 }, 258 },
  259 + {
  260 + field: 'qrcode',
  261 + label: '二维码',
  262 + component: 'Input',
  263 + colProps: {
  264 + span: 24,
  265 + },
  266 + slot: 'qrcode',
  267 + },
257 ]; 268 ];
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 import EnterpriseInfo from './components/EnterpriseInfo.vue'; 23 import EnterpriseInfo from './components/EnterpriseInfo.vue';
24 import CVIDraw from './components/CVIDraw.vue'; 24 import CVIDraw from './components/CVIDraw.vue';
25 import AppDraw from './components/AppDraw.vue'; 25 import AppDraw from './components/AppDraw.vue';
26 - const activeKey = ref('APP定制'); 26 + const activeKey = ref('企业信息');
27 </script> 27 </script>
28 28
29 <style lang="less" scoped> 29 <style lang="less" scoped>