Commit 73e026711d9b9032389af1225abaf4af5adab00e

Authored by ww
1 parent 576155d2

wip: data dashboard

  1 +import { join, resolve } from 'path';
  2 +import inquirer from 'inquirer';
  3 +import fs from 'fs-extra';
  4 +import chalk from 'chalk';
  5 +
  6 +async function genreateIcon() {
  7 + const answers = await inquirer.prompt([
  8 + {
  9 + type: 'input',
  10 + name: 'entry',
  11 + message: 'Set Iconfont.js File Entry Location!',
  12 + default: 'src/assets/iconfont/iconfont.js',
  13 + },
  14 + {
  15 + type: 'input',
  16 + name: 'output',
  17 + message: 'Set The Location For Storing Generated File!',
  18 + default: 'src/components/Icon/data',
  19 + },
  20 + {
  21 + type: 'outputFileName',
  22 + name: 'outputFileName',
  23 + message: 'Set Generate File Name!',
  24 + default: 'iconfont.data.ts',
  25 + },
  26 + ]);
  27 +
  28 + const { entry, output, outputFileName } = answers;
  29 + if (![entry, output, outputFileName].every(Boolean)) {
  30 + global.console.log(
  31 + `${chalk.yellow('Generate:Icon: ')}${chalk.red(
  32 + 'There is a problem with the file path you set!'
  33 + )}`
  34 + );
  35 + process.exit(1);
  36 + }
  37 +
  38 + const groupReg = /<symbol[^]*?<\/symbol>/g;
  39 + const getIdReg = /id=(["'])(.*?)\1/;
  40 +
  41 + const string = await fs.readFileSync(resolve(process.cwd(), entry), { encoding: 'utf-8' });
  42 +
  43 + const iconNameList = Array.from(string.matchAll(groupReg)).map(([string]) => {
  44 + const [, , name] = string.match(getIdReg) || [];
  45 + return name;
  46 + });
  47 +
  48 + await fs.writeFileSync(
  49 + join(output, outputFileName),
  50 + `export default ${JSON.stringify({ icons: iconNameList }, null, 2)}`
  51 + );
  52 +
  53 + global.console.log(
  54 + `${chalk.yellow('Generate:Icon: ')}${chalk.cyan(
  55 + 'ICon generated successfully, Store Address: '
  56 + )}${chalk.cyan(join(resolve(process.cwd()), output, outputFileName))}`
  57 + );
  58 +}
  59 +
  60 +genreateIcon();
@@ -31,7 +31,8 @@ @@ -31,7 +31,8 @@
31 "test:br": "http-server dist --cors --brotli -c-1", 31 "test:br": "http-server dist --cors --brotli -c-1",
32 "reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap", 32 "reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
33 "prepare": "husky install", 33 "prepare": "husky install",
34 - "gen:icon": "esno ./build/generate/icon/index.ts" 34 + "gen:icon": "esno ./build/generate/icon/index.ts",
  35 + "gen:iconfont": "esno ./build/generate/iconfont/index.ts"
35 }, 36 },
36 "dependencies": { 37 "dependencies": {
37 "@iconify/iconify": "^2.0.3", 38 "@iconify/iconify": "^2.0.3",
  1 +!function(t){var e,c,n,o,i,h='<svg><symbol id="iconfont-offline" viewBox="0 0 1024 1024"><path d="M932.90496 68.11648H84.25472c-44.6464 0-80.85504 38.01088-80.85504 84.82816v532.02944c0 46.8992 36.20864 84.86912 80.85504 84.86912h288.03072v97.97632H315.22816v64.26624h-73.728v82.78016h534.07744v-82.78016h-73.64608v-64.26624h-57.09824v-97.97632h288.03072c44.6464 0 80.85504-38.01088 80.85504-84.86912V152.94464c0.04096-46.81728-36.16768-84.82816-80.81408-84.82816z m-7.53664 615.8336H91.79136V154.05056h833.57696v529.89952z" ></path><path d="M670.80192 282.58304l-53.61664-54.31296-108.58496 110.05952-108.62592-110.05952-53.61664 54.31296 108.62592 110.05952-108.62592 110.10048L399.9744 557.056l108.62592-110.05952 108.58496 110.05952 53.61664-54.31296-108.62592-110.10048z" ></path></symbol><symbol id="iconfont-online" viewBox="0 0 1024 1024"><path d="M967.11 0H56.89C25.6 0 0 27.93 0 62.06v713.7c0 34.13 25.6 62.06 56.89 62.06h341.33v124.12H85.33c-14.22 0-28.44 15.52-28.44 31.03 0 15.52 14.22 31.03 28.44 31.03h853.33c14.22 0 28.44-15.51 28.44-31.03 0-15.51-14.22-31.03-28.44-31.03H625.78V837.82h341.33c31.29 0 56.89-27.93 56.89-62.06V62.06C1024 27.93 998.4 0 967.11 0zM562 934h-97.89v-99.18H562V934z m385-180H80V77h867v677zM259.46 422.85c-13.18-13.82-12.5-35.55 1.45-48.56 14.04-13.02 36.05-12.34 49.19 1.43l143.42 150.34 261.51-287.04c12.91-14.04 34.87-15.2 49.14-2.55 14.27 12.7 15.45 34.39 2.58 48.52L481.54 598.05c-6 6.55-13.97 10.31-22.21 11.17-2.13 0.4-4.29 0.59-6.46 0.59-9.24 0-18.48-3.62-25.32-10.78L259.46 422.85z" ></path></symbol><symbol id="iconfont-wind-speed" viewBox="0 0 1024 1024"><path d="M296.690688 286.65856c71.503872 0 138.81344-28.046336 190.299136-79.121408 2.009088-1.238016 3.84-2.772992 5.492736-4.48512 48.181248-50.24768 112.18432-77.88032 180.143104-77.88032 89.867264 0 174.124032 50.363392 219.942912 131.493888 8.266752 14.759936 26.923008 19.89632 41.506816 11.5712 14.645248-8.326144 19.838976-26.984448 11.51488-41.68704C889.023488 126.291968 784.397312 64 672.62464 64c-82.366464 0-159.889408 32.478208-219.052032 91.580416-1.95072 1.240064-3.779584 2.77504-5.492736 4.486144-40.503296 42.216448-94.235648 65.480704-151.389184 65.480704-65.480704 0-126.590976-30.759936-167.627776-84.43392-10.2144-13.403136-29.344768-15.941632-42.688512-5.665792-13.343744 10.268672-15.88224 29.459456-5.665792 42.863616C133.371904 247.158784 212.08064 286.65856 296.690688 286.65856z" ></path><path d="M672.62464 288.47616c-82.366464 0-159.889408 32.416768-219.052032 91.522048-1.95072 1.240064-3.779584 2.772992-5.492736 4.486144-40.503296 42.215424-94.235648 65.47968-151.389184 65.47968-65.480704 0-126.590976-30.761984-167.627776-84.431872-10.2144-13.406208-29.344768-15.942656-42.688512-5.668864-13.343744 10.27584-15.88224 29.463552-5.665792 42.86464 52.663296 68.847616 131.4304 108.34944 215.98208 108.34944 71.503872 0 138.81344-28.048384 190.359552-79.122432 1.947648-1.240064 3.77856-2.771968 5.431296-4.543488 48.181248-50.189312 112.125952-77.821952 180.143104-77.821952 89.867264 0 174.124032 50.366464 219.942912 131.49184 8.266752 14.701568 26.923008 19.84 41.506816 11.5712 14.645248-8.32512 19.838976-26.983424 11.51488-41.68704C889.023488 350.708736 784.397312 288.47616 672.62464 288.47616z" ></path><path d="M672.62464 512.896c-82.366464 0-159.889408 32.475136-219.052032 91.577344-1.95072 1.243136-3.779584 2.71872-5.492736 4.488192-40.503296 42.21952-94.235648 65.47968-151.389184 65.47968-65.480704 0-126.590976-30.761984-167.627776-84.430848-10.2144-13.406208-29.344768-15.944704-42.688512-5.668864-13.343744 10.273792-15.88224 29.463552-5.665792 42.863616 52.663296 68.845568 131.4304 108.34944 215.98208 108.34944 71.503872 0 138.81344-28.046336 190.299136-79.11936 2.009088-1.240064 3.84-2.77504 5.492736-4.544512 48.181248-50.189312 112.125952-77.822976 180.143104-77.822976 89.867264 0 174.124032 50.36544 219.942912 131.49184 8.266752 14.703616 26.923008 19.84 41.506816 11.573248 14.645248-8.32512 19.838976-26.984448 11.51488-41.684992C889.023488 575.187968 784.397312 512.896 672.62464 512.896z" ></path><path d="M672.62464 737.343488c-82.366464 0-159.889408 32.47616-219.052032 91.580416-1.95072 1.241088-3.779584 2.77504-5.492736 4.488192-40.503296 42.215424-94.235648 65.47968-151.389184 65.47968-65.480704 0-126.590976-30.761984-167.627776-84.431872-10.2144-13.406208-29.344768-15.94368-42.688512-5.668864-13.343744 10.27584-15.88224 29.462528-5.665792 42.86464 52.663296 68.847616 131.4304 108.346368 215.98208 108.346368 71.503872 0 138.81344-28.046336 190.299136-79.11936 2.009088-1.241088 3.84-2.771968 5.492736-4.543488C540.662784 826.14784 604.607488 798.5152 672.62464 798.5152c89.867264 0 174.124032 50.363392 219.942912 131.49184 8.266752 14.701568 26.923008 19.836928 41.506816 11.5712 14.645248-8.32512 19.838976-26.983424 11.51488-41.68704C889.023488 799.635456 784.397312 737.343488 672.62464 737.343488z" ></path></symbol><symbol id="iconfont-temperature" viewBox="0 0 1024 1024"><path d="M615.622 589.014V165.222c0-17.673-14.327-32-32-32H414.9c-17.673 0-32 14.327-32 32v425.62c-40.723 34.43-64.584 85.204-64.584 138.962 0 100.355 81.645 182 182 182s182-81.645 182-182c-0.001-54.925-24.643-106.364-66.694-140.79z m-115.307 258.79c-65.065 0-118-52.935-118-118 0-38.593 19.005-74.832 50.839-96.941A32.003 32.003 0 0 0 446.9 606.58V197.222h104.722v407.859a32 32 0 0 0 14.202 26.594c32.868 21.998 52.491 58.682 52.491 98.129 0 65.065-52.934 118-118 118z" ></path><path d="M516.315 670.423V466.785c0-8.836-7.164-16-16-16s-16 7.164-16 16v203.638c-26.765 7.069-46.5 31.438-46.5 60.424 0 34.518 27.982 62.5 62.5 62.5s62.5-27.982 62.5-62.5c0-28.986-19.735-53.355-46.5-60.424z" ></path></symbol><symbol id="iconfont-CO2" viewBox="0 0 1024 1024"><path d="M823.962596 339.057778c88.206222 0.739556 100.764444-5.333333 149.134222 46.933333 85.12-32.568889 45.269333-173.539556-49.607111-151.011555 9.031111-63.971556-107.093333-185.870222-208.142223-46.577778 2.872889 1.28 114.744889 48.341333 108.615112 150.656z" ></path><path d="M349.438151 512c-40.533333 0-71.466667 13.155556-92.8 40.177778-18.858667 23.466667-28.103111 54.4-28.103111 92.088889 0 38.4 8.888889 68.977778 27.022222 91.733333 20.622222 26.311111 52.266667 39.822222 94.577778 39.822222 27.392 0 50.858667-7.822222 70.4-23.466666 20.992-16.711111 34.133333-39.822222 39.822222-69.688889h-40.533333c-4.977778 19.2-13.511111 33.777778-25.6 43.377777-11.377778 8.533333-26.311111 13.155556-44.444445 13.155556-27.733333 0-48.355556-8.888889-61.511111-25.955556-12.088889-16-18.119111-39.111111-18.119111-68.977777 0-29.155556 6.044444-51.911111 18.488889-68.266667 13.511111-18.488889 33.422222-27.377778 60.074667-27.377778 17.777778 0 32.369778 3.555556 43.733333 11.377778 11.747556 7.822222 19.555556 19.911111 23.822222 36.622222h40.533334c-3.911111-25.6-14.933333-46.222222-33.422223-61.155555-19.2-15.644444-44.088889-23.466667-73.955555-23.466667z m262.755556 0c38.755556 0 69.333333 12.444444 91.733333 37.688889 21.333333 23.822222 32 55.466667 32 94.577778 0 39.111111-10.666667 70.4-32 94.222222-22.4 24.888889-52.977778 37.333333-91.733333 37.333333-39.111111 0-69.688889-12.8-91.733334-37.688889-21.333333-24.177778-31.658667-55.466667-31.658666-93.866666 0-38.755556 10.311111-70.044444 31.644444-94.222223 22.044444-25.6 52.622222-38.044444 91.733333-38.044444z m0 36.622222c-26.311111 0-46.577778 8.888889-61.155556 26.666667-13.866667 17.066667-20.622222 39.822222-20.622222 68.977778 0 28.8 6.755556 51.555556 20.622222 68.622222 14.222222 17.422222 34.844444 26.311111 61.155556 26.311111 26.311111 0 46.577778-8.533333 60.8-25.244444 13.852444-16.711111 20.963556-39.822222 20.963555-69.688889 0-29.866667-7.111111-53.333333-20.963555-70.4-14.222222-17.066667-34.488889-25.244444-60.814223-25.244445z" ></path><path d="M848.140373 398.364444l7.196445 3.015112c112.839111 47.075556 173.624889 148.622222 168.462222 259.925333-4.949333 107.064889-70.755556 199.708444-169.671111 224.853333l-5.191111 1.308445-712.248889-0.583111-6.656-2.275556C62.604373 861.710222 8.574151 780.586667 1.022151 693.845333-7.866738 591.886222 45.608818 499.712 159.102151 446.364444l7.594667-3.569777 18.005333-0.924445C233.839929 273.536 353.676373 176.128 493.509262 176.355556c130.545778 0.213333 242.716444 87.210667 276.337778 219.349333l78.293333 2.673778z m-141.653333 78.165334l-5.205333-37.404445c-15.985778-115.2-104.106667-190.762667-208.839111-190.933333-112.156444-0.184889-209.351111 84.707556-245.333334 242.830222l-7.537778 33.137778-67.669333 3.456c-79.744 40.234667-113.024 100.124444-107.150222 167.665778 4.764444 54.883556 36.792889 105.799111 69.205333 121.201778l720.213334 0.597333c60.387556-18.033778 102.314667-79.032889 105.699555-152.391111 3.598222-77.952-36.565333-147.697778-114.702222-183.424l-138.695111-4.736z" ></path><path d="M820.079929 618.126222c-15.402667 0-27.790222 5.191111-37.191111 15.587556-9.187556 9.799111-13.795556 22.599111-13.994667 38.584889h23.395556c0.398222-11.192889 2.801778-19.783111 7.196444-25.386667 4.408889-6.001778 10.993778-9.002667 19.783111-9.002667 8.206222 0 14.392889 1.806222 18.602667 5.603556 3.982222 3.797333 6.186667 9.6 6.186667 17.393778 0 7.992889-3.2 15.587556-9.386667 22.584889-3.996444 4.195556-10.396444 9.6-19.598222 16-16.583111 11.392-27.591111 20.195556-32.782223 26.183111-9.6 10.808889-14.193778 23.395556-14.193777 37.973333h99.555555v-20.579556h-70.371555c3.2-7.196444 12.003556-15.587556 26.595555-25.187555 13.994667-9.386667 23.978667-16.995556 29.582222-22.997333 9.201778-10.183111 13.994667-21.390222 13.994667-33.777778 0-12.8-4.408889-22.997333-13.198222-30.990222-8.988444-7.992889-20.394667-11.989333-34.176-11.989334z" ></path></symbol><symbol id="iconfont-wind-speed-1" viewBox="0 0 1024 1024"><path d="M580.266667 614.4H34.133333v68.266667h546.133334c56.32 0 102.4 46.08 102.4 102.4s-46.08 102.4-102.4 102.4-102.4-46.08-102.4-102.4h-68.266667c0 94.208 76.458667 170.666667 170.666667 170.666666s170.666667-76.458667 170.666666-170.666666-76.458667-170.666667-170.666666-170.666667zM546.133333 256C546.133333 171.349333 477.184 102.4 392.533333 102.4S238.933333 171.349333 238.933333 256h68.266667a85.333333 85.333333 0 0 1 170.666667 0 85.333333 85.333333 0 0 1-85.333334 85.333333H34.133333v68.266667h358.4c84.650667 0 153.6-68.949333 153.6-153.6zM798.037333 136.533333c-112.981333 0-204.8 91.818667-204.8 204.8h68.266667c0-75.434667 61.098667-136.533333 136.533333-136.533333s136.533333 61.098667 136.533334 136.533333-61.098667 136.533333-136.533334 136.533334H34.133333v68.266666h763.904c112.981333 0 204.8-91.818667 204.8-204.8s-92.16-204.8-204.8-204.8z" ></path></symbol></svg>',a=(a=document.getElementsByTagName("script"))[a.length-1].getAttribute("data-injectcss"),d=function(t,e){e.parentNode.insertBefore(t,e)};if(a&&!t.__iconfont__svg__cssinject__){t.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(t){console&&console.log(t)}}function l(){i||(i=!0,n())}function s(){try{o.documentElement.doScroll("left")}catch(t){return void setTimeout(s,50)}l()}e=function(){var t,e=document.createElement("div");e.innerHTML=h,h=null,(e=e.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",e=e,(t=document.body).firstChild?d(e,t.firstChild):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(e,0):(c=function(){document.removeEventListener("DOMContentLoaded",c,!1),e()},document.addEventListener("DOMContentLoaded",c,!1)):document.attachEvent&&(n=e,o=t.document,i=!1,s(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,l())})}(window);
  1 +export default {
  2 + icons: [
  3 + 'iconfont-offline',
  4 + 'iconfont-online',
  5 + 'iconfont-wind-speed',
  6 + 'iconfont-temperature',
  7 + 'iconfont-CO2',
  8 + 'iconfont-wind-speed-1',
  9 + ],
  10 +};
@@ -13,6 +13,7 @@ import { setupStore } from '/@/store'; @@ -13,6 +13,7 @@ import { setupStore } from '/@/store';
13 import { setupGlobDirectives } from '/@/directives'; 13 import { setupGlobDirectives } from '/@/directives';
14 import { setupI18n } from '/@/locales/setupI18n'; 14 import { setupI18n } from '/@/locales/setupI18n';
15 import { registerGlobComp } from '/@/components/registerGlobComp'; 15 import { registerGlobComp } from '/@/components/registerGlobComp';
  16 +import '/@/assets/iconfont/iconfont';
16 17
17 if (import.meta.env.DEV) { 18 if (import.meta.env.DEV) {
18 import('ant-design-vue/dist/antd.less'); 19 import('ant-design-vue/dist/antd.less');
  1 +import { Component } from 'vue';
  2 +import IndicatorLight from '../cpns/IndicatorLight.vue';
  3 +
  4 +export const dashboardComponentMap = new Map<string, Component>();
  5 +
  6 +dashboardComponentMap.set('IndicatorLight', IndicatorLight);
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -import '@simonwep/pickr/dist/themes/monolith.min.css'  
3 -import ColorPicker from '@simonwep/pickr'  
4 -import type { PropType } from 'vue'  
5 -import { computed, onMounted, onUnmounted, ref, unref } from 'vue'  
6 -  
7 -type Format = Exclude<keyof ColorPicker.HSVaColor, 'clone'>  
8 -  
9 -const props = defineProps({  
10 - value: {  
11 - type: String,  
12 - default: '#377dff',  
13 - },  
14 - format: {  
15 - type: String as PropType<ColorPicker.Representation>,  
16 - default: 'HEXA' as ColorPicker.Representation,  
17 - },  
18 - config: {  
19 - type: Object as PropType<ColorPicker.Options>,  
20 - },  
21 -})  
22 -  
23 -const emit = defineEmits(['update:value'])  
24 -  
25 -const prefixCls = 'thingskit'  
26 -  
27 -const colorPickerCls = 'color-picker'  
28 -  
29 -const picker = ref<Nullable<ColorPicker>>(null)  
30 -  
31 -const getFormat = computed<Format>(() => {  
32 - return `to${props.format}`  
33 -})  
34 -  
35 -const getColor = () => {  
36 - const value = unref(picker)?.getColor()  
37 - return value && value[unref(getFormat)]().toString()  
38 -}  
39 -  
40 -const onInit = () => {  
41 - unref(picker)?.setColor(props.value)  
42 -}  
43 -  
44 -const onSave = () => {  
45 - const value = getColor()  
46 - emit('update:value', value)  
47 - unref(picker)?.hide()  
48 -}  
49 -  
50 -const getOption = computed<ColorPicker.Options>(() => {  
51 - const { config = {} } = props  
52 - return {  
53 - theme: 'monolith',  
54 - components: {  
55 - // Main components  
56 - preview: true,  
57 - opacity: true,  
58 - hue: true,  
59 -  
60 - // Input / output Options  
61 - interaction: {  
62 - hex: true,  
63 - rgba: true,  
64 - input: true,  
65 - clear: true,  
66 - save: true,  
67 - }, 2 + import '@simonwep/pickr/dist/themes/monolith.min.css';
  3 + import ColorPicker from '@simonwep/pickr';
  4 + import type { PropType } from 'vue';
  5 + import { computed, onMounted, onUnmounted, ref, unref } from 'vue';
  6 +
  7 + type Format = Exclude<keyof ColorPicker.HSVaColor, 'clone'>;
  8 +
  9 + const props = defineProps({
  10 + value: {
  11 + type: String,
  12 + default: '#377dff',
68 }, 13 },
69 - i18n: {  
70 - 'ui:dialog': 'color picker dialog',  
71 - 'btn:toggle': 'toggle color picker dialog',  
72 - 'btn:swatch': 'color swatch',  
73 - 'btn:last-color': '使用以前的颜色',  
74 - 'btn:save': '保存',  
75 - 'btn:cancel': '取消',  
76 - 'btn:clear': '清除',  
77 -  
78 - // 用于 aria-labels 的字符串  
79 - 'aria:btn:save': 'save and close',  
80 - 'aria:btn:cancel': 'cancel and close',  
81 - 'aria:btn:clear': 'clear and close',  
82 - 'aria:input': '颜色输入字段',  
83 - 'aria:palette': '颜色选择区域',  
84 - 'aria:hue': '色调选择滑块',  
85 - 'aria:opacity': '选择滑块', 14 + format: {
  15 + type: String as PropType<ColorPicker.Representation>,
  16 + default: 'HEXA' as ColorPicker.Representation,
86 }, 17 },
87 - ...config, 18 + config: {
  19 + type: Object as PropType<ColorPicker.Options>,
  20 + },
  21 + });
  22 +
  23 + const emit = defineEmits(['update:value']);
  24 +
  25 + const prefixCls = 'thingskit';
  26 +
  27 + const colorPickerCls = 'color-picker';
  28 +
  29 + const picker = ref<Nullable<ColorPicker>>(null);
  30 +
  31 + const getFormat = computed<Format>(() => {
  32 + return `to${props.format}`;
  33 + });
  34 +
  35 + const getColor = () => {
  36 + const value = unref(picker)?.getColor();
  37 + return value && value[unref(getFormat)]().toString();
  38 + };
  39 +
  40 + const onInit = () => {
  41 + unref(picker)?.setColor(props.value);
  42 + };
  43 +
  44 + const onSave = () => {
  45 + const value = getColor();
  46 + emit('update:value', value);
  47 + unref(picker)?.hide();
  48 + };
  49 +
  50 + const getOption = computed<ColorPicker.Options>(() => {
  51 + const { config = {} } = props;
  52 + return {
  53 + theme: 'monolith',
  54 + components: {
  55 + // Main components
  56 + preview: true,
  57 + opacity: true,
  58 + hue: true,
  59 +
  60 + // Input / output Options
  61 + interaction: {
  62 + hex: true,
  63 + rgba: true,
  64 + input: true,
  65 + clear: true,
  66 + save: true,
  67 + },
  68 + },
  69 + i18n: {
  70 + 'ui:dialog': 'color picker dialog',
  71 + 'btn:toggle': 'toggle color picker dialog',
  72 + 'btn:swatch': 'color swatch',
  73 + 'btn:last-color': '使用以前的颜色',
  74 + 'btn:save': '保存',
  75 + 'btn:cancel': '取消',
  76 + 'btn:clear': '清除',
  77 +
  78 + // 用于 aria-labels 的字符串
  79 + 'aria:btn:save': 'save and close',
  80 + 'aria:btn:cancel': 'cancel and close',
  81 + 'aria:btn:clear': 'clear and close',
  82 + 'aria:input': '颜色输入字段',
  83 + 'aria:palette': '颜色选择区域',
  84 + 'aria:hue': '色调选择滑块',
  85 + 'aria:opacity': '选择滑块',
  86 + },
  87 + ...config,
88 88
89 - el: `.${prefixCls}-${colorPickerCls}`,  
90 - }  
91 -}) 89 + el: `.${prefixCls}-${colorPickerCls}`,
  90 + };
  91 + });
92 92
93 -onMounted(() => {  
94 - picker.value = ColorPicker.create(unref(getOption))  
95 - unref(picker)?.on('init', onInit)  
96 - unref(picker)?.on('save', onSave)  
97 -}) 93 + onMounted(() => {
  94 + picker.value = ColorPicker.create(unref(getOption));
  95 + unref(picker)?.on('init', onInit);
  96 + unref(picker)?.on('save', onSave);
  97 + });
98 98
99 -onUnmounted(() => {  
100 - unref(picker)?.off('init', onInit)  
101 - unref(picker)?.off('save', onSave) 99 + onUnmounted(() => {
  100 + unref(picker)?.off('init', onInit);
  101 + unref(picker)?.off('save', onSave);
102 102
103 - unref(picker)?.destroyAndRemove()  
104 -}) 103 + unref(picker)?.destroyAndRemove();
  104 + });
105 </script> 105 </script>
106 106
107 <template> 107 <template>
108 - <div :class="`${prefixCls}-${colorPickerCls}`" /> 108 + <div :class="`${prefixCls}-${colorPickerCls}`"></div>
109 </template> 109 </template>
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -import icon from '../assets/command.svg' 2 + import icon from '../assets/command.svg';
3 3
4 -const props = defineProps<{  
5 - value?: boolean  
6 -}>() 4 + const props = defineProps<{
  5 + value?: boolean;
  6 + }>();
7 7
8 -const emit = defineEmits(['update:value', 'change']) 8 + const emit = defineEmits(['update:value', 'change']);
9 9
10 -const handleChange = (event: Event) => {  
11 - const _value = (event.target as HTMLInputElement).checked  
12 - emit('update:value', _value)  
13 - emit('change', _value)  
14 -} 10 + const handleChange = (event: Event) => {
  11 + const _value = (event.target as HTMLInputElement).checked;
  12 + emit('update:value', _value);
  13 + emit('change', _value);
  14 + };
15 </script> 15 </script>
16 16
17 <template> 17 <template>
18 <div class="command-send-button"> 18 <div class="command-send-button">
19 123 19 123
20 <a href="javascript:;"> 20 <a href="javascript:;">
21 - <img :src="icon" alt=""> 21 + <img :src="icon" alt="" />
22 </a> 22 </a>
23 </div> 23 </div>
24 </template> 24 </template>
25 25
26 <style scoped lang="less"> 26 <style scoped lang="less">
27 -.command-send-button {  
28 - width: 80px;  
29 - height: 60px;  
30 - position: relative;  
31 -  
32 - a {  
33 - position: absolute;  
34 - box-sizing: border-box;  
35 - cursor: pointer;  
36 - text-decoration: none;  
37 - color: #fff;  
38 - background: #f2385a;  
39 - top: 0;  
40 - padding: 0 16px;  
41 - height: 60px; 27 + .command-send-button {
42 width: 80px; 28 width: 80px;
43 - overflow: hidden;  
44 - font-size: 20px;  
45 - line-height: 60px;  
46 - border-radius: 10px;  
47 - box-shadow: 0 15px 0 0 #f02046, 0 0 20px 0 #bbb;  
48 - transition: all 0.2s;  
49 - } 29 + height: 60px;
  30 + position: relative;
50 31
51 -} 32 + a {
  33 + position: absolute;
  34 + box-sizing: border-box;
  35 + cursor: pointer;
  36 + text-decoration: none;
  37 + color: #fff;
  38 + background: #f2385a;
  39 + top: 0;
  40 + padding: 0 16px;
  41 + height: 60px;
  42 + width: 80px;
  43 + overflow: hidden;
  44 + font-size: 20px;
  45 + line-height: 60px;
  46 + border-radius: 10px;
  47 + box-shadow: 0 15px 0 0 #f02046, 0 0 20px 0 #bbb;
  48 + transition: all 0.2s;
  49 + }
  50 + }
52 </style> 51 </style>
1 -<script lang="ts">  
2 -import { defineComponent } from 'vue'  
3 -  
4 -export default defineComponent({  
5 - props: {  
6 - msg: String,  
7 - },  
8 - setup(props) {  
9 -  
10 - },  
11 -})  
12 -</script>  
13 -  
14 -<template>  
15 - <div>{{ msg }}</div>  
16 -</template>  
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -const props = defineProps<{  
3 - value?: boolean  
4 -}>() 2 + const props = defineProps<{
  3 + value?: boolean;
  4 + }>();
5 5
6 -const emit = defineEmits(['update:value', 'change']) 6 + const emit = defineEmits(['update:value', 'change']);
7 7
8 -const handleChange = (event: Event) => {  
9 - const _value = (event.target as HTMLInputElement).checked  
10 - emit('update:value', _value)  
11 - emit('change', _value)  
12 -} 8 + const handleChange = (event: Event) => {
  9 + const _value = (event.target as HTMLInputElement).checked;
  10 + emit('update:value', _value);
  11 + emit('change', _value);
  12 + };
13 </script> 13 </script>
14 14
15 <template> 15 <template>
16 <label class="indicator-light-switch"> 16 <label class="indicator-light-switch">
17 - <input :value="props.value" :checked="props.value" type="checkbox" @change="handleChange">  
18 - <div class="panel" /> 17 + <input :value="props.value" :checked="props.value" type="checkbox" @change="handleChange" />
  18 + <div class="panel"></div>
19 </label> 19 </label>
20 </template> 20 </template>
21 21
22 <style scoped lang="less"> 22 <style scoped lang="less">
23 -.indicator-light-switch {  
24 - input[type='checkbox'] {  
25 - display: none;  
26 - }  
27 - .panel {  
28 - position: relative;  
29 - width: 60px;  
30 - height: 60px;  
31 - cursor: pointer;  
32 - border-radius: 50%;  
33 - background: linear-gradient(#dedede, #fdfdfd);  
34 - box-shadow: 0 3px 5px rgb(0 0 0 / 25%), inset 0 1px 0 hsl(0deg 0% 100% / 30%), inset 0 -5px 5px hsl(0deg 0% 39% / 10%), inset 0 5px 5px hsl(0deg 0% 100% / 30%);  
35 - } 23 + .indicator-light-switch {
  24 + input[type='checkbox'] {
  25 + display: none;
  26 + }
  27 + .panel {
  28 + position: relative;
  29 + width: 60px;
  30 + height: 60px;
  31 + cursor: pointer;
  32 + border-radius: 50%;
  33 + background: linear-gradient(#dedede, #fdfdfd);
  34 + box-shadow: 0 3px 5px rgb(0 0 0 / 25%), inset 0 1px 0 hsl(0deg 0% 100% / 30%),
  35 + inset 0 -5px 5px hsl(0deg 0% 39% / 10%), inset 0 5px 5px hsl(0deg 0% 100% / 30%);
  36 + }
36 37
37 - .panel::after,  
38 - .panel::before {  
39 - content: '';  
40 - position: absolute;  
41 - width: 20%;  
42 - height: 20%;  
43 - border-radius: 50%;  
44 - left: 40%;  
45 - top: 40%;  
46 - } 38 + .panel::after,
  39 + .panel::before {
  40 + content: '';
  41 + position: absolute;
  42 + width: 20%;
  43 + height: 20%;
  44 + border-radius: 50%;
  45 + left: 40%;
  46 + top: 40%;
  47 + }
47 48
48 - input:checked ~ .panel::after {  
49 - display: none;  
50 - } 49 + input:checked ~ .panel::after {
  50 + display: none;
  51 + }
51 52
52 - input:not(:checked) ~ .panel::before {  
53 - display: none;  
54 - } 53 + input:not(:checked) ~ .panel::before {
  54 + display: none;
  55 + }
55 56
56 - input:not(:checked) ~ .panel {  
57 - background: linear-gradient(#EAEAEA, #eaeaea);  
58 - } 57 + input:not(:checked) ~ .panel {
  58 + background: linear-gradient(#eaeaea, #eaeaea);
  59 + }
59 60
60 - .panel::after {  
61 - background-color: #ddd;  
62 - background: radial-gradient(40% 35%, #ccc, #969696 60%);  
63 - box-shadow: inset 0 2px 1px rgb(0 0 0 / 15%), 0 2px 5px hsl(0deg 0% 78% / 10%);  
64 - } 61 + .panel::after {
  62 + background-color: #ddd;
  63 + background: radial-gradient(40% 35%, #ccc, #969696 60%);
  64 + box-shadow: inset 0 2px 1px rgb(0 0 0 / 15%), 0 2px 5px hsl(0deg 0% 78% / 10%);
  65 + }
65 66
66 - .panel::before {  
67 - background-color: #25d025;  
68 - box-shadow: inset 0 3px 5px 1px rgb(0 0 0 / 10%), 0 1px 0 hsl(0deg 0% 100% / 40%), 0 0 10px 2px rgb(0 210 0 / 50%); 67 + .panel::before {
  68 + background-color: #25d025;
  69 + box-shadow: inset 0 3px 5px 1px rgb(0 0 0 / 10%), 0 1px 0 hsl(0deg 0% 100% / 40%),
  70 + 0 0 10px 2px rgb(0 210 0 / 50%);
  71 + }
69 } 72 }
70 -}  
71 </style> 73 </style>
  1 +<script lang="ts" setup>
  2 + import { SvgIcon } from '/@/components/Icon';
  3 + import { Statistic } from 'ant-design-vue';
  4 +
  5 + const props = defineProps({
  6 + icon: {
  7 + type: String,
  8 + default: 'wind-speed',
  9 + },
  10 + color: {
  11 + type: String,
  12 + default: 'blue',
  13 + },
  14 + updateTime: {
  15 + type: String,
  16 + default: '2022-08-26 11:11:23',
  17 + },
  18 + });
  19 +</script>
  20 +
  21 +<template>
  22 + <section class="flex flex-col h-full justify-center">
  23 + <div class="flex items-center">
  24 + <div class="flex flex-col justify-center items-center">
  25 + <SvgIcon :style="{ color: props.color }" :name="props.icon" prefix="iconfont" />
  26 + <div class="text-sm my-2">温度</div>
  27 + </div>
  28 + <div class="text-center flex-auto">
  29 + <Statistic
  30 + value="123"
  31 + :value-style="{ display: 'flex', fontSize: '12px', justifyContent: 'center' }"
  32 + :suffix="'%'"
  33 + />
  34 + </div>
  35 + </div>
  36 + <div class="text-xs text-gray-500 text-center truncate" :title="props.updateTime">
  37 + 更新时间: {{ props.updateTime }}
  38 + </div>
  39 + </section>
  40 +</template>
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -import on from '../assets/light-bulb-on.svg'  
3 -import off from '../assets/light-bulb-off.svg' 2 + import on from '../assets/light-bulb-on.svg';
  3 + import off from '../assets/light-bulb-off.svg';
4 4
5 -const props = defineProps<{  
6 - value?: boolean  
7 -}>() 5 + const props = defineProps<{
  6 + value?: boolean;
  7 + }>();
8 8
9 -const emit = defineEmits(['update:value', 'change']) 9 + const emit = defineEmits(['update:value', 'change']);
10 10
11 -const handleChange = (event: Event) => {  
12 - const _value = (event.target as HTMLInputElement).checked  
13 - emit('update:value', _value)  
14 - emit('change', _value)  
15 -} 11 + const handleChange = (event: Event) => {
  12 + const _value = (event.target as HTMLInputElement).checked;
  13 + emit('update:value', _value);
  14 + emit('change', _value);
  15 + };
16 </script> 16 </script>
17 17
18 <template> 18 <template>
19 <label class="light-bulb-switch"> 19 <label class="light-bulb-switch">
20 - <input :value="props.value" :checked="props.value" type="checkbox" @change="handleChange">  
21 - <div class="light-bulb__on">  
22 - <img :src="on" alt="开">  
23 - </div>  
24 - <div class="light-bulb__off">  
25 - <img :src="off" alt="关">  
26 - </div> 20 + <input :value="props.value" :checked="props.value" type="checkbox" @change="handleChange" />
  21 + <div class="light-bulb__on"> <img :src="on" alt="开" /> </div>
  22 + <div class="light-bulb__off"> <img :src="off" alt="关" /> </div>
27 </label> 23 </label>
28 </template> 24 </template>
29 25
30 <style scoped lang="less"> 26 <style scoped lang="less">
31 -.light-bulb-switch {  
32 - input[type='checkbox'] {  
33 - display: none; 27 + .light-bulb-switch {
  28 + input[type='checkbox'] {
  29 + display: none;
  30 + }
  31 +
  32 + input:checked ~ .light-bulb__off {
  33 + display: none;
  34 + }
  35 +
  36 + input:not(:checked) ~ .light-bulb__on {
  37 + display: none;
  38 + }
  39 +
  40 + .light-bulb__on > img,
  41 + .light-bulb__off > img {
  42 + width: 48px;
  43 + height: 48px;
  44 + cursor: pointer;
  45 + }
34 } 46 }
35 -  
36 - input:checked ~ .light-bulb__off {  
37 - display: none;  
38 - }  
39 -  
40 - input:not(:checked) ~ .light-bulb__on {  
41 - display: none;  
42 - }  
43 -  
44 - .light-bulb__on > img,  
45 - .light-bulb__off > img {  
46 - width: 48px;  
47 - height: 48px;  
48 - cursor: pointer;  
49 - }  
50 -}  
51 </style> 47 </style>
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -const props = defineProps<{  
3 - value?: boolean  
4 -}>() 2 + const props = defineProps<{
  3 + value?: boolean;
  4 + }>();
5 5
6 -const emit = defineEmits(['update:value', 'change']) 6 + const emit = defineEmits(['update:value', 'change']);
7 7
8 -const handleChange = (event: Event) => {  
9 - const _value = (event.target as HTMLInputElement).checked  
10 - emit('update:value', _value)  
11 - emit('change', _value)  
12 -} 8 + const handleChange = (event: Event) => {
  9 + const _value = (event.target as HTMLInputElement).checked;
  10 + emit('update:value', _value);
  11 + emit('change', _value);
  12 + };
13 </script> 13 </script>
14 14
15 <template> 15 <template>
16 <label class="rocker-switch"> 16 <label class="rocker-switch">
17 - <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange"> 17 + <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange" />
18 <span class="switch-left">ON</span> 18 <span class="switch-left">ON</span>
19 <span class="switch-right">OFF</span> 19 <span class="switch-right">OFF</span>
20 </label> 20 </label>
21 </template> 21 </template>
22 22
23 <style scoped lang="less"> 23 <style scoped lang="less">
24 -.rocker-switch {  
25 - display: flex;  
26 - width: 72px;  
27 - font-size: 14px;  
28 - color: #fff;  
29 - font-weight: 700;  
30 - letter-spacing: 1px;  
31 - border: 0.5em solid #eee;  
32 - background-color: #999;  
33 - user-select: none; 24 + .rocker-switch {
  25 + display: flex;
  26 + width: 72px;
  27 + font-size: 14px;
  28 + color: #fff;
  29 + font-weight: 700;
  30 + letter-spacing: 1px;
  31 + border: 0.5em solid #eee;
  32 + background-color: #999;
  33 + user-select: none;
34 34
35 - input[type='checkbox'] {  
36 - display: none;  
37 - } 35 + input[type='checkbox'] {
  36 + display: none;
  37 + }
38 38
39 - input:checked + .switch-left + .switch-right {  
40 - transform: rotate(-15deg) skew(-15deg) translate(-1px, -5px);  
41 - }  
42 - input:checked + .switch-left + .switch-right::before {  
43 - background-color: #ccc;  
44 - content: '';  
45 - position: absolute;  
46 - width: 3px;  
47 - height: 30px;  
48 - transform: skewY(75deg) skewX(4deg) rotate(5deg) translateX(1px);  
49 - top: 1.5px;  
50 - right: -1.5px;  
51 - } 39 + input:checked + .switch-left + .switch-right {
  40 + transform: rotate(-15deg) skew(-15deg) translate(-1px, -5px);
  41 + }
  42 + input:checked + .switch-left + .switch-right::before {
  43 + background-color: #ccc;
  44 + content: '';
  45 + position: absolute;
  46 + width: 3px;
  47 + height: 30px;
  48 + transform: skewY(75deg) skewX(4deg) rotate(5deg) translateX(1px);
  49 + top: 1.5px;
  50 + right: -1.5px;
  51 + }
52 52
53 - input + .switch-left {  
54 - transform: rotate(15deg) skew(17deg) translate(1px, -5px);  
55 - } 53 + input + .switch-left {
  54 + transform: rotate(15deg) skew(17deg) translate(1px, -5px);
  55 + }
56 56
57 - input:checked + .switch-left {  
58 - background-color: #0084d0;  
59 - transform: none;  
60 - } 57 + input:checked + .switch-left {
  58 + background-color: #0084d0;
  59 + transform: none;
  60 + }
61 61
62 - input:not(:checked) + .switch-left {  
63 - background-color: #ccc;  
64 - } 62 + input:not(:checked) + .switch-left {
  63 + background-color: #ccc;
  64 + }
65 65
66 - input:not(:checked) + .switch-left + .switch-right {  
67 - background-color: #bd5757;  
68 - color: #fff;  
69 - } 66 + input:not(:checked) + .switch-left + .switch-right {
  67 + background-color: #bd5757;
  68 + color: #fff;
  69 + }
70 70
71 - input + .switch-left::before {  
72 - background-color: #ccc;  
73 - content: '';  
74 - position: absolute;  
75 - width: 3px;  
76 - height: 30px;  
77 - background-color: #ccc;  
78 - transform: skewY(-75deg) skewX(-4deg) rotate(-5deg) translateX(-1.5px);  
79 - top: -1.5px;  
80 - left: -1.5px;  
81 - } 71 + input + .switch-left::before {
  72 + background-color: #ccc;
  73 + content: '';
  74 + position: absolute;
  75 + width: 3px;
  76 + height: 30px;
  77 + background-color: #ccc;
  78 + transform: skewY(-75deg) skewX(-4deg) rotate(-5deg) translateX(-1.5px);
  79 + top: -1.5px;
  80 + left: -1.5px;
  81 + }
82 82
83 - .switch-left {  
84 - width: 36px;  
85 - height: 30px;  
86 - text-align: center;  
87 - line-height: 30px;  
88 - cursor: pointer;  
89 - } 83 + .switch-left {
  84 + width: 36px;
  85 + height: 30px;
  86 + text-align: center;
  87 + line-height: 30px;
  88 + cursor: pointer;
  89 + }
90 90
91 - .switch-right {  
92 - color: #888;  
93 - width: 36px;  
94 - height: 30px;  
95 - text-align: center;  
96 - line-height: 30px;  
97 - background-color: #ddd;  
98 - cursor: pointer; 91 + .switch-right {
  92 + color: #888;
  93 + width: 36px;
  94 + height: 30px;
  95 + text-align: center;
  96 + line-height: 30px;
  97 + background-color: #ddd;
  98 + cursor: pointer;
  99 + }
99 } 100 }
100 -}  
101 </style> 101 </style>
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -const props = defineProps<{  
3 - value?: boolean  
4 -}>() 2 + const props = defineProps<{
  3 + value?: boolean;
  4 + }>();
5 5
6 -const emit = defineEmits(['update:value', 'change']) 6 + const emit = defineEmits(['update:value', 'change']);
7 7
8 -const handleChange = (event: Event) => {  
9 - const _value = (event.target as HTMLInputElement).checked  
10 - emit('update:value', _value)  
11 - emit('change', _value)  
12 -} 8 + const handleChange = (event: Event) => {
  9 + const _value = (event.target as HTMLInputElement).checked;
  10 + emit('update:value', _value);
  11 + emit('change', _value);
  12 + };
13 </script> 13 </script>
14 14
15 <template> 15 <template>
16 <label class="sliding-switch"> 16 <label class="sliding-switch">
17 - <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange">  
18 - <span class="slider" /> 17 + <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange" />
  18 + <span class="slider"></span>
19 <span class="on">ON</span> 19 <span class="on">ON</span>
20 <span class="off">OFF</span> 20 <span class="off">OFF</span>
21 </label> 21 </label>
22 </template> 22 </template>
23 23
24 <style scoped lang="less"> 24 <style scoped lang="less">
25 -.sliding-switch {  
26 - position: relative;  
27 - display: block;  
28 - font-weight: 700;  
29 - line-height: 40px;  
30 - width: 80px;  
31 - height: 40px;  
32 - font-size: 14px;  
33 - cursor: pointer;  
34 - user-select: none;  
35 -  
36 - input[type='checkbox'] {  
37 - display: none;  
38 - }  
39 -  
40 - .slider { 25 + .sliding-switch {
  26 + position: relative;
  27 + display: block;
  28 + font-weight: 700;
  29 + line-height: 40px;
41 width: 80px; 30 width: 80px;
42 height: 40px; 31 height: 40px;
43 - box-sizing: border-box;  
44 - position: absolute;  
45 - top: 0;  
46 - left: 0;  
47 - right: 0;  
48 - bottom: 0;  
49 - border: 2px solid #ecf0f3;  
50 - border-radius: 20px;  
51 - box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%), inset -2px -2px 8px #fff, inset -2px -2px 12px hsl(0deg 0% 100% / 50%), inset 2px 2px 4px hsl(0deg 0% 100% / 10%),  
52 - inset 2px 2px 8px rgb(0 0 0 / 30%), 2px 2px 8px rgb(0 0 0 / 30%);  
53 - background-color: #ecf0f3;  
54 - z-index: -1;  
55 - }  
56 -  
57 - .slider::after {  
58 - position: absolute; 32 + font-size: 14px;
59 cursor: pointer; 33 cursor: pointer;
60 - display: block;  
61 - content: '';  
62 - width: 24px;  
63 - height: 24px;  
64 - border-radius: 50%;  
65 - top: 6px;  
66 - left: 6px;  
67 - background-color: #ecf0f3;  
68 - box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%), inset 2px 2px 4px hsl(0deg 0% 100% / 10%), 2px 2px 8px rgb(0 0 0 / 30%);  
69 - z-index: 999;  
70 - transition: 0.5s;  
71 - } 34 + user-select: none;
72 35
73 - input:checked ~ .off {  
74 - opacity: 0;  
75 - } 36 + input[type='checkbox'] {
  37 + display: none;
  38 + }
76 39
77 - input:checked ~ .slider::after {  
78 - transform: translateX(35px);  
79 - }  
80 - input:not(:checked) ~ .on {  
81 - opacity: 0;  
82 - transform: translateX(0px);  
83 - } 40 + .slider {
  41 + width: 80px;
  42 + height: 40px;
  43 + box-sizing: border-box;
  44 + position: absolute;
  45 + top: 0;
  46 + left: 0;
  47 + right: 0;
  48 + bottom: 0;
  49 + border: 2px solid #ecf0f3;
  50 + border-radius: 20px;
  51 + box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%),
  52 + inset -2px -2px 8px #fff, inset -2px -2px 12px hsl(0deg 0% 100% / 50%),
  53 + inset 2px 2px 4px hsl(0deg 0% 100% / 10%), inset 2px 2px 8px rgb(0 0 0 / 30%),
  54 + 2px 2px 8px rgb(0 0 0 / 30%);
  55 + background-color: #ecf0f3;
  56 + z-index: -1;
  57 + }
84 58
85 - .on,  
86 - .off {  
87 - display: inline-block;  
88 - margin-left: 3px;  
89 - width: 34px;  
90 - text-align: center;  
91 - transition: 0.2s;  
92 - } 59 + .slider::after {
  60 + position: absolute;
  61 + cursor: pointer;
  62 + display: block;
  63 + content: '';
  64 + width: 24px;
  65 + height: 24px;
  66 + border-radius: 50%;
  67 + top: 6px;
  68 + left: 6px;
  69 + background-color: #ecf0f3;
  70 + box-shadow: -2px -2px 8px #fff, -2px -2px 12px hsl(0deg 0% 100% / 50%),
  71 + inset 2px 2px 4px hsl(0deg 0% 100% / 10%), 2px 2px 8px rgb(0 0 0 / 30%);
  72 + z-index: 999;
  73 + transition: 0.5s;
  74 + }
93 75
94 - .on {  
95 - color: #039be5;  
96 - }  
97 - .off {  
98 - color: #999; 76 + input:checked ~ .off {
  77 + opacity: 0;
  78 + }
  79 +
  80 + input:checked ~ .slider::after {
  81 + transform: translateX(35px);
  82 + }
  83 + input:not(:checked) ~ .on {
  84 + opacity: 0;
  85 + transform: translateX(0px);
  86 + }
  87 +
  88 + .on,
  89 + .off {
  90 + display: inline-block;
  91 + margin-left: 3px;
  92 + width: 34px;
  93 + text-align: center;
  94 + transition: 0.2s;
  95 + }
  96 +
  97 + .on {
  98 + color: #039be5;
  99 + }
  100 + .off {
  101 + color: #999;
  102 + }
99 } 103 }
100 -}  
101 </style> 104 </style>
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 -const props = defineProps<{  
3 - value?: boolean  
4 -}>() 2 + const props = defineProps<{
  3 + value?: boolean;
  4 + }>();
5 5
6 -const emit = defineEmits(['update:value', 'change']) 6 + const emit = defineEmits(['update:value', 'change']);
7 7
8 -const handleChange = (event: Event) => {  
9 - const _value = (event.target as HTMLInputElement).checked  
10 - emit('update:value', _value)  
11 - emit('change', _value)  
12 -} 8 + const handleChange = (event: Event) => {
  9 + const _value = (event.target as HTMLInputElement).checked;
  10 + emit('update:value', _value);
  11 + emit('change', _value);
  12 + };
13 </script> 13 </script>
14 14
15 <template> 15 <template>
16 <div class="toggle-switch"> 16 <div class="toggle-switch">
17 <label class="switch"> 17 <label class="switch">
18 - <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange"> 18 + <input :value="props.value" type="checkbox" :checked="props.value" @change="handleChange" />
19 <div class="button"> 19 <div class="button">
20 - <div class="light" />  
21 - <div class="dots" />  
22 - <div class="characters" />  
23 - <div class="shine" />  
24 - <div class="shadow" /> 20 + <div class="light"></div>
  21 + <div class="dots"></div>
  22 + <div class="characters"></div>
  23 + <div class="shine"></div>
  24 + <div class="shadow"></div>
25 </div> 25 </div>
26 </label> 26 </label>
27 </div> 27 </div>
28 </template> 28 </template>
29 29
30 <style scoped> 30 <style scoped>
31 -.toggle-switch {  
32 - flex: 1 1 auto;  
33 - max-width: 75px;  
34 - height: 97.5px;  
35 - display: flex;  
36 -}  
37 -  
38 -.switch {  
39 - background-color: black;  
40 - box-sizing: border-box;  
41 - width: 100%;  
42 - height: 100%;  
43 - box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black, inset 0 2px 2px -2px white, inset 0 0 2px 15px #47434c, inset 0 0 2px 22px black;  
44 - border-radius: 5px;  
45 - padding: 10px;  
46 - perspective: 700px;  
47 -}  
48 -  
49 -.switch input {  
50 - display: none;  
51 -}  
52 -  
53 -.switch input:checked + .button {  
54 - transform: translateZ(20px) rotateX(25deg);  
55 - box-shadow: 0 -5px 10px #ff1818;  
56 -}  
57 -  
58 -.switch input:checked + .button .light {  
59 - animation: flicker 0.2s infinite 0.3s;  
60 -}  
61 -  
62 -.switch input:checked + .button .shine {  
63 - opacity: 1;  
64 -}  
65 -  
66 -.switch input:checked + .button .shadow {  
67 - opacity: 0;  
68 -}  
69 -  
70 -.switch .button {  
71 - display: flex;  
72 - justify-content: center;  
73 - align-items: center;  
74 - transition: all 0.3s cubic-bezier(1, 0, 1, 1);  
75 - transform-origin: center center -20px;  
76 - transform: translateZ(20px) rotateX(-25deg);  
77 - transform-style: preserve-3d;  
78 - background-color: #9b0621;  
79 - width: 100%;  
80 - height: 100%;  
81 - position: relative;  
82 - cursor: pointer;  
83 - background: linear-gradient(#980000 0%, #6f0000 30%, #6f0000 70%, #980000 100%);  
84 - background-repeat: no-repeat;  
85 -}  
86 -  
87 -.switch .button::before {  
88 - content: '';  
89 - background: linear-gradient(rgba(255, 255, 255, 0.8) 10%, rgba(255, 255, 255, 0.3) 30%, #650000 75%, #320000) 50% 50%/97% 97%, #b10000;  
90 - background-repeat: no-repeat;  
91 - width: 100%;  
92 - height: 30px;  
93 - transform-origin: top;  
94 - transform: rotateX(-90deg);  
95 - position: absolute;  
96 - top: 0;  
97 -}  
98 -  
99 -.switch .button::after {  
100 - content: '';  
101 - background-image: linear-gradient(#650000, #320000);  
102 - width: 100%;  
103 - height: 30px;  
104 - transform-origin: top;  
105 - transform: translateY(30px) rotateX(-90deg);  
106 - position: absolute;  
107 - bottom: 0;  
108 - box-shadow: 0 30px 8px 0px black, 0 60px 20px 0px rgb(0 0 0 / 50%);  
109 -}  
110 -  
111 -.switch .light {  
112 - opacity: 0;  
113 - animation: light-off 1s;  
114 - position: absolute;  
115 - width: 80%;  
116 - height: 80%;  
117 - background-image: radial-gradient(#ffc97e, transparent 40%), radial-gradient(circle, #ff1818 50%, transparent 80%);  
118 -}  
119 -  
120 -.switch .dots {  
121 - position: absolute;  
122 - width: 100%;  
123 - height: 100%;  
124 - background-image: radial-gradient(transparent 30%, rgba(101, 0, 0, 0.7) 70%);  
125 - background-size: 10px 10px;  
126 -}  
127 -  
128 -.switch .characters {  
129 - position: absolute;  
130 - width: 100%;  
131 - height: 100%;  
132 - background: linear-gradient(white, white) 50% 20%/5% 20%, radial-gradient(circle, transparent 50%, white 52%, white 70%, transparent 72%) 50% 80%/33% 25%;  
133 - background-repeat: no-repeat;  
134 -}  
135 -  
136 -.switch .shine {  
137 - transition: all 0.3s cubic-bezier(1, 0, 1, 1);  
138 - opacity: 0.3;  
139 - position: absolute;  
140 - width: 100%;  
141 - height: 100%;  
142 - background: linear-gradient(white, transparent 3%) 50% 50%/97% 97%, linear-gradient(rgba(255, 255, 255, 0.5), transparent 50%, transparent 80%, rgba(255, 255, 255, 0.5)) 50% 50%/97% 97%;  
143 - background-repeat: no-repeat;  
144 -}  
145 -  
146 -.switch .shadow {  
147 - transition: all 0.3s cubic-bezier(1, 0, 1, 1);  
148 - opacity: 1;  
149 - position: absolute;  
150 - width: 100%;  
151 - height: 100%;  
152 - background: linear-gradient(transparent 70%, rgba(0, 0, 0, 0.8));  
153 - background-repeat: no-repeat;  
154 -}  
155 -  
156 -@keyframes flicker {  
157 - 0% {  
158 - opacity: 1; 31 + .toggle-switch {
  32 + flex: 1 1 auto;
  33 + max-width: 75px;
  34 + height: 97.5px;
  35 + display: flex;
159 } 36 }
160 37
161 - 80% {  
162 - opacity: 0.8; 38 + .switch {
  39 + background-color: black;
  40 + box-sizing: border-box;
  41 + width: 100%;
  42 + height: 100%;
  43 + box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px black, inset 0 2px 2px -2px white,
  44 + inset 0 0 2px 15px #47434c, inset 0 0 2px 22px black;
  45 + border-radius: 5px;
  46 + padding: 10px;
  47 + perspective: 700px;
163 } 48 }
164 49
165 - 100% {  
166 - opacity: 1; 50 + .switch input {
  51 + display: none;
  52 + }
  53 +
  54 + .switch input:checked + .button {
  55 + transform: translateZ(20px) rotateX(25deg);
  56 + box-shadow: 0 -5px 10px #ff1818;
167 } 57 }
168 -}  
169 58
170 -@keyframes light-off {  
171 - 0% { 59 + .switch input:checked + .button .light {
  60 + animation: flicker 0.2s infinite 0.3s;
  61 + }
  62 +
  63 + .switch input:checked + .button .shine {
172 opacity: 1; 64 opacity: 1;
173 } 65 }
174 66
175 - 80% { 67 + .switch input:checked + .button .shadow {
  68 + opacity: 0;
  69 + }
  70 +
  71 + .switch .button {
  72 + display: flex;
  73 + justify-content: center;
  74 + align-items: center;
  75 + transition: all 0.3s cubic-bezier(1, 0, 1, 1);
  76 + transform-origin: center center -20px;
  77 + transform: translateZ(20px) rotateX(-25deg);
  78 + transform-style: preserve-3d;
  79 + background-color: #9b0621;
  80 + width: 100%;
  81 + height: 100%;
  82 + position: relative;
  83 + cursor: pointer;
  84 + background: linear-gradient(#980000 0%, #6f0000 30%, #6f0000 70%, #980000 100%);
  85 + background-repeat: no-repeat;
  86 + }
  87 +
  88 + .switch .button::before {
  89 + content: '';
  90 + background: linear-gradient(
  91 + rgba(255, 255, 255, 0.8) 10%,
  92 + rgba(255, 255, 255, 0.3) 30%,
  93 + #650000 75%,
  94 + #320000
  95 + )
  96 + 50% 50%/97% 97%,
  97 + #b10000;
  98 + background-repeat: no-repeat;
  99 + width: 100%;
  100 + height: 30px;
  101 + transform-origin: top;
  102 + transform: rotateX(-90deg);
  103 + position: absolute;
  104 + top: 0;
  105 + }
  106 +
  107 + .switch .button::after {
  108 + content: '';
  109 + background-image: linear-gradient(#650000, #320000);
  110 + width: 100%;
  111 + height: 30px;
  112 + transform-origin: top;
  113 + transform: translateY(30px) rotateX(-90deg);
  114 + position: absolute;
  115 + bottom: 0;
  116 + box-shadow: 0 30px 8px 0px black, 0 60px 20px 0px rgb(0 0 0 / 50%);
  117 + }
  118 +
  119 + .switch .light {
176 opacity: 0; 120 opacity: 0;
  121 + animation: light-off 1s;
  122 + position: absolute;
  123 + width: 80%;
  124 + height: 80%;
  125 + background-image: radial-gradient(#ffc97e, transparent 40%),
  126 + radial-gradient(circle, #ff1818 50%, transparent 80%);
  127 + }
  128 +
  129 + .switch .dots {
  130 + position: absolute;
  131 + width: 100%;
  132 + height: 100%;
  133 + background-image: radial-gradient(transparent 30%, rgba(101, 0, 0, 0.7) 70%);
  134 + background-size: 10px 10px;
  135 + }
  136 +
  137 + .switch .characters {
  138 + position: absolute;
  139 + width: 100%;
  140 + height: 100%;
  141 + background: linear-gradient(white, white) 50% 20%/5% 20%,
  142 + radial-gradient(circle, transparent 50%, white 52%, white 70%, transparent 72%) 50% 80%/33%
  143 + 25%;
  144 + background-repeat: no-repeat;
  145 + }
  146 +
  147 + .switch .shine {
  148 + transition: all 0.3s cubic-bezier(1, 0, 1, 1);
  149 + opacity: 0.3;
  150 + position: absolute;
  151 + width: 100%;
  152 + height: 100%;
  153 + background: linear-gradient(white, transparent 3%) 50% 50%/97% 97%,
  154 + linear-gradient(
  155 + rgba(255, 255, 255, 0.5),
  156 + transparent 50%,
  157 + transparent 80%,
  158 + rgba(255, 255, 255, 0.5)
  159 + )
  160 + 50% 50%/97% 97%;
  161 + background-repeat: no-repeat;
  162 + }
  163 +
  164 + .switch .shadow {
  165 + transition: all 0.3s cubic-bezier(1, 0, 1, 1);
  166 + opacity: 1;
  167 + position: absolute;
  168 + width: 100%;
  169 + height: 100%;
  170 + background: linear-gradient(transparent 70%, rgba(0, 0, 0, 0.8));
  171 + background-repeat: no-repeat;
  172 + }
  173 +
  174 + @keyframes flicker {
  175 + 0% {
  176 + opacity: 1;
  177 + }
  178 +
  179 + 80% {
  180 + opacity: 0.8;
  181 + }
  182 +
  183 + 100% {
  184 + opacity: 1;
  185 + }
  186 + }
  187 +
  188 + @keyframes light-off {
  189 + 0% {
  190 + opacity: 1;
  191 + }
  192 +
  193 + 80% {
  194 + opacity: 0;
  195 + }
177 } 196 }
178 -}  
179 </style> 197 </style>
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 import Dropdown from '/@/components/Dropdown/src/Dropdown.vue'; 4 import Dropdown from '/@/components/Dropdown/src/Dropdown.vue';
5 import { Tooltip } from 'ant-design-vue'; 5 import { Tooltip } from 'ant-design-vue';
6 import Icon from '/@/components/Icon/src/Icon.vue'; 6 import Icon from '/@/components/Icon/src/Icon.vue';
  7 + import SvgIcon from '/@/components/Icon/src/SvgIcon.vue';
7 enum MoreEvent { 8 enum MoreEvent {
8 EDIT = 'edit', 9 EDIT = 'edit',
9 COPY = 'copy', 10 COPY = 'copy',
@@ -39,9 +40,9 @@ @@ -39,9 +40,9 @@
39 <div v-for="item in 3" class="flex mx-2" :key="item"> 40 <div v-for="item in 3" class="flex mx-2" :key="item">
40 <div class="flex items-center"> 41 <div class="flex items-center">
41 <Tooltip> 42 <Tooltip>
42 - <Icon icon="ant-design:edit-outlined" /> 43 + <SvgIcon name="online" prefix="iconfont" class="!fill-emerald-400" />
43 </Tooltip> 44 </Tooltip>
44 - <span class="truncate max-w-25">设备名称{{ item }}</span> 45 + <span class="truncate max-w-25 ml-2">设备名称{{ item }}</span>
45 </div> 46 </div>
46 </div> 47 </div>
47 </div> 48 </div>
@@ -2,9 +2,9 @@ @@ -2,9 +2,9 @@
2 import { Button, PageHeader } from 'ant-design-vue'; 2 import { Button, PageHeader } from 'ant-design-vue';
3 import { GridItem, GridLayout, Layout } from 'vue3-grid-layout'; 3 import { GridItem, GridLayout, Layout } from 'vue3-grid-layout';
4 import { nextTick, ref } from 'vue'; 4 import { nextTick, ref } from 'vue';
5 - import BaseDashboard from '../cpns/Dashboard/BaseDashboard.vue';  
6 import WidgetWrapper from '../cpns/WidgetWrapper/WidgetWrapper.vue'; 5 import WidgetWrapper from '../cpns/WidgetWrapper/WidgetWrapper.vue';
7 import BaseWidgetHeader from '../cpns/WidgetHeader/BaseWidgetHeader.vue'; 6 import BaseWidgetHeader from '../cpns/WidgetHeader/BaseWidgetHeader.vue';
  7 + import InformationPanel from '../cpns/InformationPanel.vue';
8 const handleBack = () => {}; 8 const handleBack = () => {};
9 9
10 interface ChartAttr { 10 interface ChartAttr {
@@ -32,13 +32,13 @@ @@ -32,13 +32,13 @@
32 chart: [ 32 chart: [
33 { id: 'a', width: 100, height: 100 }, 33 { id: 'a', width: 100, height: 100 },
34 { id: 'b', width: 100, height: 100 }, 34 { id: 'b', width: 100, height: 100 },
35 - { id: 'c', width: 100, height: 100 },  
36 - { id: 'd', width: 100, height: 100 },  
37 - { id: 'e', width: 100, height: 100 },  
38 - { id: 'f', width: 100, height: 100 },  
39 - { id: 'g', width: 100, height: 100 },  
40 - { id: 'h', width: 100, height: 100 },  
41 - { id: 'i', width: 100, height: 100 }, 35 + // { id: 'c', width: 100, height: 100 },
  36 + // { id: 'd', width: 100, height: 100 },
  37 + // { id: 'e', width: 100, height: 100 },
  38 + // { id: 'f', width: 100, height: 100 },
  39 + // { id: 'g', width: 100, height: 100 },
  40 + // { id: 'h', width: 100, height: 100 },
  41 + // { id: 'i', width: 100, height: 100 },
42 ], 42 ],
43 }, 43 },
44 { 44 {
@@ -52,12 +52,12 @@ @@ -52,12 +52,12 @@
52 { id: 'j', width: 100, height: 100 }, 52 { id: 'j', width: 100, height: 100 },
53 { id: 'k', width: 100, height: 100 }, 53 { id: 'k', width: 100, height: 100 },
54 { id: 'l', width: 100, height: 100 }, 54 { id: 'l', width: 100, height: 100 },
55 - { id: 'm', width: 100, height: 100 },  
56 - { id: 'n', width: 100, height: 100 },  
57 - { id: 'o', width: 100, height: 100 },  
58 - { id: 'p', width: 100, height: 100 },  
59 - { id: 'q', width: 100, height: 100 },  
60 - { id: 'r', width: 100, height: 100 }, 55 + // { id: 'm', width: 100, height: 100 },
  56 + // { id: 'n', width: 100, height: 100 },
  57 + // { id: 'o', width: 100, height: 100 },
  58 + // { id: 'p', width: 100, height: 100 },
  59 + // { id: 'q', width: 100, height: 100 },
  60 + // { id: 'r', width: 100, height: 100 },
61 ], 61 ],
62 }, 62 },
63 ]); 63 ]);
@@ -187,17 +187,10 @@ @@ -187,17 +187,10 @@
187 <BaseWidgetHeader /> 187 <BaseWidgetHeader />
188 </template> 188 </template>
189 <template #controls="{ record, add }"> 189 <template #controls="{ record, add }">
190 - <!-- <ToggleSwitch /> -->  
191 - <!-- <SlidingSwitch @change="handleChange" /> --> 190 + <InformationPanel />
192 <!-- <LightBulbSwitch @change="handleChange" /> --> 191 <!-- <LightBulbSwitch @change="handleChange" /> -->
193 <!-- <div :id="getControlsWidgetId(record.id)" class="widget-charts" /> --> 192 <!-- <div :id="getControlsWidgetId(record.id)" class="widget-charts" /> -->
194 - <BaseDashboard :data-source="record" :add="add" />  
195 - </template>  
196 - <template #value="{ record }">  
197 - <span>{{ record.id }}</span>  
198 - </template>  
199 - <template #label="{ record }">  
200 - <span>{{ record.id }}</span> 193 + <!-- <BaseDashboard :data-source="record" :add="add" /> -->
201 </template> 194 </template>
202 </WidgetWrapper> 195 </WidgetWrapper>
203 </GridItem> 196 </GridItem>