Commit e1f24fe949d7db9a55656e45bd580d235f988fc3

Authored by fengtao
2 parents 504c9662 15b854ff

Merge branch 'main' into ft-dev

... ... @@ -2,7 +2,7 @@
2 2 VITE_PORT = 8083
3 3
4 4 # spa-title
5   -VITE_GLOB_APP_TITLE = Yunteng IOT
  5 +VITE_GLOB_APP_TITLE = Things Kit
6 6
7 7 # spa shortname
8 8 # VITE_GLOB_APP_SHORT_NAME = Yunteng IOT
... ...

186 KB | W: | H:

195 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
... ... @@ -69,6 +69,7 @@ export default {
69 69 backSignIn: 'Back sign in',
70 70 mobileSignInFormTitle: 'Mobile sign in',
71 71 qrSignInFormTitle: 'Qr code sign in',
  72 + userNameInFormTitle: 'userName sign in',
72 73 signInFormTitle: 'Sign in',
73 74 signUpFormTitle: 'Sign up',
74 75 forgetFormTitle: 'Reset password',
... ...
... ... @@ -65,7 +65,7 @@ export default {
65 65 qrSignInFormTitle: '二维码登录',
66 66 signUpFormTitle: '注册',
67 67 forgetFormTitle: '重置密码',
68   -
  68 + userNameInFormTitle: '账号登录',
69 69 signInTitle: '物联网平台',
70 70 signInDesc: '输入您的个人详细信息开始使用!',
71 71 policy: '我同意xxx隐私政策',
... ...
1 1 import '/@/design/index.less';
2   -
3 2 // Register windi
4 3 import 'virtual:windi.css';
5 4 // Register icon sprite
... ... @@ -19,10 +18,6 @@ if (import.meta.env.DEV) {
19 18 }
20 19 async function bootstrap() {
21 20 const app = createApp(App);
22   -
23   - // app.use(VueBaidu, {
24   - // ak: '7uOPPyAHn2Y2ZryeQqHtcRqtIY374vKa',
25   - // });
26 21 // Configure store
27 22 setupStore(app);
28 23
... ...
... ... @@ -44,7 +44,7 @@ export const useUserStore = defineStore({
44 44 id: 'app-user',
45 45 state: (): UserState => ({
46 46 //平台信息
47   - platInfo: storage.get('platInfo') || null,
  47 + platInfo: storage.get('platformInfo') || null,
48 48 enterPriseInfo: storage.get('enterPriseInfo') || null,
49 49 // user info
50 50 userInfo: null,
... ...
... ... @@ -3,7 +3,7 @@
3 3 <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666">
4 4 <div class="flex" style="height: 100px">
5 5 <div class="mr-4"
6   - ><img src="/src/assets/svg/device-num.svg" style="width: 5.625rem; height: 5.625rem"
  6 + ><img src="/src/assets/images/device-count.png" style="width: 5.625rem; height: 5.625rem"
7 7 /></div>
8 8 <div class="flex-auto">
9 9 <div class="flex justify-between" style="align-items: center">
... ... @@ -17,31 +17,36 @@
17 17 <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
18 18 </div>
19 19 <div> 设备数(个) </div>
  20 + <div class="flex" style="align-items: center">
  21 + <div class="mr-2"
  22 + >在线
  23 + <span style="color: #41b883">{{ growCardList?.deviceInfo?.onLine ?? 0 }}</span></div
  24 + >
  25 + <div class="mr-2">
  26 + 离线
  27 + <span style="color: #f5222d">{{ growCardList?.deviceInfo?.offLine ?? 0 }} </span></div
  28 + >
  29 +
  30 + <div>
  31 + 未激活
  32 + <span style="color: #fa8c16">{{ growCardList?.deviceInfo?.inActive ?? 0 }}</span>
  33 + </div>
  34 + </div>
20 35 </div>
21 36 </div>
22 37 <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
23   - <div class="flex" style="align-items: center">
24   - <span class="mr-2">在线{{ growCardList?.deviceInfo?.onLine }}</span>
25   -
26   - <span class="mr-2"> 离线{{ growCardList?.deviceInfo?.offLine }} </span>
27   -
28   - <span> 未激活{{ growCardList?.deviceInfo?.inActive }} </span>
29   - </div></div
30   - >
  38 + 今日新增 {{ toThousands(growCardList?.deviceInfo?.todayAdd) }}
  39 + </div>
31 40 </Card>
32 41 <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666">
33 42 <div class="flex" style="height: 100px">
34 43 <div class="mr-4">
35 44 <img
36 45 v-if="!isAdmin(role)"
37   - src="/src/assets/svg/alarm-num.svg"
38   - style="width: 5.625rem; height: 5.625rem"
39   - />
40   - <img
41   - v-else
42   - src="/src/assets/svg/tenant-num.svg"
  46 + src="/src/assets/images/alarm-count.png"
43 47 style="width: 5.625rem; height: 5.625rem"
44 48 />
  49 + <img v-else src="/src/assets/images/zh.png" style="width: 5.625rem; height: 5.625rem" />
45 50 </div>
46 51 <div class="flex-auto">
47 52 <div class="flex justify-between" style="align-items: center">
... ... @@ -61,7 +66,7 @@
61 66 </div>
62 67 <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
63 68 </div>
64   - <div> {{ !isAdmin(role) ? `告警数(条)` : '租户总量(个)' }}</div>
  69 + <div> {{ !isAdmin(role) ? `告警数(条)` : '租户总量(个)' }}</div>
65 70 </div>
66 71 </div>
67 72 <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
... ... @@ -76,13 +81,9 @@
76 81 <div class="mr-4"
77 82 ><img
78 83 v-if="!isAdmin(role)"
79   - src="/src/assets/svg/msg-num.svg"
80   - style="width: 5.625rem; height: 5.625rem"
81   - /><img
82   - v-else
83   - src="/src/assets/svg/custom-num.svg"
  84 + src="/src/assets/images/msg-count.png"
84 85 style="width: 5.625rem; height: 5.625rem"
85   - />
  86 + /><img v-else src="/src/assets/images/kf.png" style="width: 5.625rem; height: 5.625rem" />
86 87 </div>
87 88 <div v-if="!isAdmin(role)" style="display: flex; align-items: center">
88 89 <div>
... ... @@ -94,7 +95,7 @@
94 95 />
95 96 <CountTo v-else :end-val="0" />
96 97 </div>
97   - 消息量(条)
  98 + 消息量(条)
98 99 </div>
99 100 <div>
100 101 <span class="mr-2">数据点</span>
... ...
... ... @@ -15,7 +15,7 @@
15 15 >
16 16 <List item-layout="horizontal" :dataSource="dataSource">
17 17 <template #renderItem="{ item }">
18   - <ListItem>
  18 + <ListItem @click="go('/notice/myNotices')" class="cursor-pointer">
19 19 <ListItemMeta>
20 20 <template #avatar>
21 21 <Avatar
... ... @@ -24,11 +24,7 @@
24 24 />
25 25 </template>
26 26 <template #description>
27   - <span
28   - class="cursor-pointer noticeTitle"
29   - @click="go('/stationnotification/mynotification')"
30   - >{{ item.sysNotice.title }}
31   - </span>
  27 + <span class="cursor-pointer noticeTitle">{{ item.sysNotice.title }} </span>
32 28 </template>
33 29 <template #title>
34 30 <span>{{ item.sysNotice.senderName }}</span>
... ... @@ -52,9 +48,9 @@
52 48 </template>
53 49 <CardMeta>
54 50 <template #description>
55   - <p>联系人: {{ getContacts }}</p>
56   - <p>联系电话: {{ getTel }}</p>
57   - <p>联系地址: {{ getAddress }} </p>
  51 + <p v-if="getContacts">联系人: {{ getContacts }}</p>
  52 + <p v-if="getTel">联系电话: {{ getTel }}</p>
  53 + <p v-if="getAddress">联系地址: {{ getAddress }} </p>
58 54 </template>
59 55 </CardMeta>
60 56 </Card>
... ...
... ... @@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
57 57 const enable = status === '已发布' ? '已发布' : status === '草稿' ? '草稿' : '其他';
58 58 const color = enable === '已发布' ? 'green' : enable === '草稿' ? 'yellow' : 'red';
59 59 const text = enable === '已发布' ? '已发布' : enable === '草稿' ? '草稿' : '其他';
60   - return h(Tag, { color: color }, () => text);
  60 + return h(Tag, { color }, () => text);
61 61 },
62 62 },
63 63 ];
... ... @@ -172,7 +172,7 @@ export const searchFormSchema: FormSchema[] = [
172 172 export const detailColumns: BasicColumn[] = [
173 173 {
174 174 title: '接收者',
175   - dataIndex: 'user.realName',
  175 + dataIndex: 'receiverName',
176 176 width: 200,
177 177 },
178 178 {
... ...
... ... @@ -38,7 +38,6 @@
38 38 <ForgetPasswordForm />
39 39 <RegisterForm />
40 40 <MobileForm />
41   - <QrCodeForm />
42 41 </div>
43 42 </div>
44 43 </div>
... ... @@ -46,14 +45,13 @@
46 45 </div>
47 46 </template>
48 47 <script lang="ts" setup>
49   - import { computed, ref } from 'vue';
  48 + import { computed } from 'vue';
50 49 import { AppLogo } from '/@/components/Application';
51 50 import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application';
52 51 import LoginForm from './LoginForm.vue';
53 52 import ForgetPasswordForm from './ForgetPasswordForm.vue';
54 53 import RegisterForm from './RegisterForm.vue';
55 54 import MobileForm from './MobileForm.vue';
56   - import QrCodeForm from './QrCodeForm.vue';
57 55 import { useGlobSetting } from '/@/hooks/setting';
58 56 import { useI18n } from '/@/hooks/web/useI18n';
59 57 import { useDesign } from '/@/hooks/web/useDesign';
... ...
... ... @@ -49,13 +49,13 @@
49 49 </FormItem>
50 50 <ARow class="enter-x flex justify-between">
51 51 <ACol :md="11" :xs="24">
52   - <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
53   - {{ t('sys.login.mobileSignInFormTitle') }}
  52 + <Button block @click="setLoginState(LoginStateEnum.LOGIN)">
  53 + {{ t('sys.login.userNameInFormTitle') }}
54 54 </Button>
55 55 </ACol>
56 56 <ACol :md="11" :xs="24">
57   - <Button block @click="setLoginState(LoginStateEnum.QR_CODE)">
58   - {{ t('sys.login.qrSignInFormTitle') }}
  57 + <Button block @click="setLoginState(LoginStateEnum.MOBILE)">
  58 + {{ t('sys.login.mobileSignInFormTitle') }}
59 59 </Button>
60 60 </ACol>
61 61 </ARow>
... ... @@ -86,23 +86,28 @@
86 86
87 87 const { setLoginState, getLoginState } = useLoginState();
88 88 const { getFormRules } = useFormRules();
  89 + const storage = createLocalStorage();
89 90
90 91 const formRef = ref();
91 92 const loading = ref(false);
92 93 const rememberMe = ref(false);
93   -
  94 + const userInfo = storage.get('userInfo');
94 95 const formData = reactive({
95   - account: '',
96   - password: '',
  96 + account: userInfo?.account ?? '',
  97 + password: userInfo?.password ?? '',
97 98 });
98 99
99 100 const { validForm } = useFormValid(formRef);
100 101
101 102 const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
102   - const storage = createLocalStorage();
103 103 async function handleLogin() {
104 104 const data = await validForm();
105 105 if (!data) return;
  106 + if (unref(rememberMe)) {
  107 + storage.set('userInfo', formData);
  108 + } else {
  109 + storage.set('userInfo', null);
  110 + }
106 111 try {
107 112 loading.value = true;
108 113 const userInfo = await userStore.login({
... ...
... ... @@ -4,6 +4,7 @@
4 4 title="第一次使用请修改当前用户密码,待修改完成后退出登录,才能使用本系统!"
5 5 content="修改成功后会自动退出当前登录!"
6 6 class="p-4"
  7 + :contentStyle="{ margin: '16px 0 ' }"
7 8 >
8 9 <div class="py-8 bg-white flex flex-col justify-center items-center">
9 10 <BasicForm @register="register" />
... ...
... ... @@ -224,7 +224,7 @@
224 224 // 保存store
225 225 userStore.setPlatInfo(newFieldValue);
226 226 // 保存本地缓存
227   - storage.set('platInfo', newFieldValue);
  227 + storage.set('platformInfo', newFieldValue);
228 228 }
229 229
230 230 onMounted(async () => {
... ...
... ... @@ -301,7 +301,6 @@
301 301 setFieldsValue({ nameCountry: codeCountry });
302 302 }
303 303 setFieldsValue(res);
304   - console.log(res);
305 304 qrcodePic.value = res.qrCode;
306 305 });
307 306
... ...
... ... @@ -26,7 +26,7 @@
26 26 </BasicDrawer>
27 27 </template>
28 28 <script lang="ts">
29   - import { defineComponent, ref, computed, unref, watch } from 'vue';
  29 + import { defineComponent, ref, computed, unref } from 'vue';
30 30 import { BasicForm, useForm } from '/@/components/Form/index';
31 31 import { formSchema } from './role.data';
32 32 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
... ... @@ -54,9 +54,6 @@
54 54 schemas: formSchema,
55 55 showActionButtonGroup: false,
56 56 });
57   - watch(roleMenus, (newValue) => {
58   - console.log(newValue);
59   - });
60 57
61 58 // 递归函数,将RouteItem里面的字段换名称
62 59 function processChildren(items: RouteItem[]) {
... ... @@ -79,7 +76,7 @@
79 76 arr.splice(index, 1);
80 77 return arr;
81 78 }
82   -
  79 + const originMenus = ref();
83 80 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
84 81 resetFields();
85 82 roleId.value = '';
... ... @@ -95,6 +92,7 @@
95 92 if (unref(isUpdate)) {
96 93 //通过角色id去获取角色对应的菜单的ids
97 94 roleMenus.value = await getMenusIdsByRoleId(data.record.id);
  95 + originMenus.value = [...roleMenus.value];
98 96 for (let m of treeData.value) {
99 97 for (let m1 of roleMenus.value) {
100 98 // 利用continue特性优化一下性能
... ... @@ -103,6 +101,7 @@
103 101 }
104 102 }
105 103 treeRef.value.setCheckedKeys(roleMenus.value);
  104 + console.log(originMenus.value);
106 105 roleId.value = data.record.id;
107 106 setFieldsValue(data.record);
108 107 }
... ... @@ -119,7 +118,7 @@
119 118 name: values.name,
120 119 remark: values.remark,
121 120 status: values.status,
122   - menu: allCheckedKeys.value.length ? allCheckedKeys.value : roleMenus.value,
  121 + menu: allCheckedKeys.value.length ? allCheckedKeys.value : originMenus.value,
123 122 };
124 123 saveOrUpdateRoleInfoWithMenu(req).then(() => {
125 124 closeDrawer();
... ...
... ... @@ -78,7 +78,7 @@
78 78 arr.splice(index, 1);
79 79 return arr;
80 80 }
81   -
  81 + const originMenus = ref();
82 82 const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
83 83 resetFields();
84 84 roleId.value = '';
... ... @@ -94,6 +94,7 @@
94 94 if (unref(isUpdate)) {
95 95 //通过角色id去获取角色对应的菜单的ids
96 96 roleMenus.value = await getMenusIdsByRoleId(data.record.id);
  97 + originMenus.value = [...roleMenus.value];
97 98 for (let m of treeData.value) {
98 99 for (let m1 of roleMenus.value) {
99 100 // 利用continue特性优化一下性能
... ... @@ -118,7 +119,7 @@
118 119 remark: values.remark,
119 120 status: values.status,
120 121 roleType: RoleEnum.TENANT_ADMIN,
121   - menu: allCheckedKeys.value.length ? allCheckedKeys.value : roleMenus.value,
  122 + menu: allCheckedKeys.value.length ? allCheckedKeys.value : originMenus.value,
122 123 };
123 124 await saveOrUpdateRoleInfoWithMenu(req);
124 125 closeDrawer();
... ...