Repository: xdlumia/lingo Branch: main Commit: 5e2ab8fc659c Files: 48 Total size: 234.8 KB Directory structure: gitextract_jqcymo_h/ ├── .gitignore ├── README.md ├── babel.config.js ├── package.json ├── public/ │ └── index.html ├── src/ │ ├── App.vue │ ├── api/ │ │ └── index.js │ ├── components/ │ │ ├── app-group-nav.vue │ │ ├── date-time.vue │ │ ├── fm.vue │ │ ├── header.vue │ │ ├── login.vue │ │ ├── music.vue │ │ ├── pinned.vue │ │ ├── public/ │ │ │ ├── d-icon.vue │ │ │ ├── d-modal.vue │ │ │ └── d-tabs.vue │ │ ├── search-box.vue │ │ ├── sidebar/ │ │ │ ├── add/ │ │ │ │ └── default.vue │ │ │ ├── add.vue │ │ │ ├── index.vue │ │ │ ├── note.vue │ │ │ ├── setting/ │ │ │ │ ├── about.vue │ │ │ │ ├── exterior.vue │ │ │ │ ├── index.vue │ │ │ │ ├── theme.vue │ │ │ │ ├── user.vue │ │ │ │ └── wallpaper.vue │ │ │ ├── todo.vue │ │ │ └── weather.vue │ │ └── yiyan.vue │ ├── iconfont/ │ │ └── iconfont.js │ ├── json/ │ │ └── index.js │ ├── main.js │ ├── store/ │ │ └── index.js │ ├── style/ │ │ ├── animate.less │ │ ├── base.less │ │ ├── common.less │ │ ├── element.less │ │ ├── index.less │ │ ├── reset.less │ │ └── theme.less │ ├── utils/ │ │ ├── directives.js │ │ ├── filters.js │ │ ├── localStrong.js │ │ └── utils.js │ └── views/ │ └── home.vue └── vue.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store node_modules /search /newTabs/dist/* newTabs.zip # local env files .env.local .env.*.local # Log files npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: README.md ================================================ # initial2 ## Project setup ``` yarn install ``` ### Compiles and hot-reloads for development ``` yarn serve ``` ### Compiles and minifies for production ``` yarn build ``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). ================================================ FILE: babel.config.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-13 07:59:11 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-27 15:21:58 * @Description: file content */ module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ], plugins: [ // element官方教程 [ "component", { libraryName: "element-ui", styleLibraryName: "theme-chalk", style: true } ] ] } ================================================ FILE: package.json ================================================ { "name": "lingo", "version": "0.2.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "dev": "cross-env NODE_ENV=web vue-cli-service serve", "dev:web": "cross-env NODE_ENV=web vue-cli-service serve", "build": "vue-cli-service build", "build:web": "cross-env NODE_ENV=web vue-cli-service", "b": "vue-cli-service build && cross-env NODE_ENV=web vue-cli-service build" }, "dependencies": { "axios": "^0.21.0", "core-js": "^3.6.5", "dayjs": "^1.9.4", "element-ui": "^2.14.0", "js-base64": "^3.6.0", "vue": "^2.6.12", "vue-clipboard2": "^0.3.1", "vue-swiper": "^0.5.0", "vuedraggable": "^2.24.3", "vuex": "^3.5.1" }, "devDependencies": { "global": "^4.4.0", "@vue/cli-plugin-babel": "~4.5.8", "@vue/cli-plugin-router": "~4.5.8", "@vue/cli-service": "~4.5.8", "babel-plugin-component": "^1.1.1", "cross-env": "^7.0.2", "less": "^3.12.2", "less-loader": "^7.0.2", "vue-template-compiler": "^2.6.12" }, "browserslist": [ "> 1%", "last 2 versions", "not dead" ] } ================================================ FILE: public/index.html ================================================ lingo新标签页
================================================ FILE: src/App.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-10 10:04:55 * @LastEditors: itab.link * @LastEditTime: 2022-01-12 20:56:02 * @Description: file content */ ================================================ FILE: src/api/index.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-13 08:52:34 * @LastEditors: www.itab.link * @LastEditTime: 2022-01-13 00:12:54 * @Description: file content */ import axios from 'axios' import store from '@/store' import { Message } from 'element-ui' import local from '@/utils/localStrong'; import QS from 'querystring'; axios.defaults.paramsSerializer = function (params) { return QS.stringify(params); }; axios.interceptors.request.use(config => { // config.headers.token = (local.get('userInfo') || {}).token || '' return config }) // 响应拦截器 axios.interceptors.response.use(response => { let res = response.data if (res.code == 500) { Message.error(res.msg) } else if (res.code == 400) { Message.error('登陆已过期,请重新登陆') // 清空用户信息 store.commit('setUserInfo', null) // 调用登陆的弹出框 store.commit("setLoginInfo", { visible: true, type: 'login', }); } return response.data }) let baseUrl = 'http://localhost:8081' //振兴 let dreamwqApi = 'http://localhost:8081' //api // let dreamwqApi = 'http://localhost:8081' //api // let baseUrl = 'apis/' export default { // 登陆 login(params) { return axios.post(`${baseUrl}/index/login`, params); }, // 注册 register(params) { return axios.post(`${baseUrl}/index/register`, params); }, // 保存配置 configInfoSave(params) { return axios.post(`${baseUrl}/configInfo/saveOrUpdate`, params, { headers: { token: (local.get('userInfo') || {}).token || '' } }); }, // 获取配置 configInfoCurInfo(params) { return axios.get(`${baseUrl}/configInfo/curInfo`, { params: params, headers: { token: (local.get('userInfo') || {}).token || '' } }); }, //获取根据用户ip获取位置信息 getCityLocal() { return axios.get(`${dreamwqApi}/api/getLocation`); }, //获取实况天气 getWeather(cid) { return axios.get(`https://widget-api.heweather.net/s6/plugin/h5?key=db9bb478dfb943949c821628a67011e9&location=${cid}&lang=cn`); }, //获取一言 getYiyan(params) { return axios.get('https://v1.hitokoto.cn/?c=d&c=i&encode=json', params); }, //百度搜索 baiduSugrec(params) { return axios.get(`${dreamwqApi}/api/baidu_sugrec/${params}`); }, //获取豆瓣fm getDoubanFm(params) { return axios.get(`${dreamwqApi}/api/fm/playlist`, { params }); }, //获取网站站点 getWebsiteList(params) { return axios.get(`${dreamwqApi}/website/list`, { params }); }, }; ================================================ FILE: src/components/app-group-nav.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 17:48:38 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-06-09 15:46:42 * @Description: 应用列表 */ ================================================ FILE: src/components/date-time.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-14 16:38:27 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-05-31 11:12:13 * @Description: 时间 */ ================================================ FILE: src/components/fm.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-14 12:38:18 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-28 11:26:10 * @Description: FM */ ================================================ FILE: src/components/header.vue ================================================ ================================================ FILE: src/components/login.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-15 21:52:45 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-12-07 16:43:44 * @Description: 注册 */ ================================================ FILE: src/components/music.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-14 12:38:18 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-01-19 11:12:30 * @Description: FM */ ================================================ FILE: src/components/pinned.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-23 10:09:07 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-30 09:09:43 * @Description: pinned */ ================================================ FILE: src/components/public/d-icon.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-27 10:31:35 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-28 10:22:49 * @Description: file content */ ================================================ FILE: src/components/public/d-modal.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 17:48:38 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-30 08:44:59 * @Description: 应用列表 */ ================================================ FILE: src/components/public/d-tabs.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-27 16:37:58 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-27 16:57:46 * @Description: file content */ ================================================ FILE: src/components/search-box.vue ================================================ ================================================ FILE: src/components/sidebar/add/default.vue ================================================ ================================================ FILE: src/components/sidebar/add.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-01-19 17:17:46 * @Description: add 添加和修改图标 */ ================================================ FILE: src/components/sidebar/index.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 17:48:38 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-27 10:56:07 * @Description: file content */ ================================================ FILE: src/components/sidebar/note.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-27 11:20:25 * @Description: note */ ================================================ FILE: src/components/sidebar/setting/about.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-15 21:52:45 * @LastEditors: www.itab.link * @LastEditTime: 2022-01-13 00:13:08 * @Description: setting 关于我 */ ================================================ FILE: src/components/sidebar/setting/exterior.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-01-20 09:43:20 * @Description: setting 外观 */ ================================================ FILE: src/components/sidebar/setting/index.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-12-04 14:47:33 * @Description: setting 设置 */ ================================================ FILE: src/components/sidebar/setting/theme.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-15 21:52:45 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-27 15:12:48 * @Description: setting 主题 */ ================================================ FILE: src/components/sidebar/setting/user.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-15 21:52:45 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-12-07 17:00:49 * @Description: setting 主题 */ ================================================ FILE: src/components/sidebar/setting/wallpaper.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: www.itab.link * @LastEditTime: 2022-01-13 00:13:24 * @Description: 设置-壁纸 */ ================================================ FILE: src/components/sidebar/todo.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-12-07 17:59:42 * @Description: todo */ ================================================ FILE: src/components/sidebar/weather.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-12 18:03:48 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-06-10 14:46:22 * @Description: 天气 */ ================================================ FILE: src/components/yiyan.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-14 12:38:18 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-01-20 09:55:08 * @Description: 一言 */ ================================================ FILE: src/iconfont/iconfont.js ================================================ !function(l){var a,c,h,o,i,t,m='',z=(z=document.getElementsByTagName("script"))[z.length-1].getAttribute("data-injectcss");if(z&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}function s(){i||(i=!0,h())}a=function(){var l,a,c,h;(h=document.createElement("div")).innerHTML=m,m=null,(c=h.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",l=c,(a=document.body).firstChild?(h=l,(c=a.firstChild).parentNode.insertBefore(h,c)):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(c=function(){document.removeEventListener("DOMContentLoaded",c,!1),a()},document.addEventListener("DOMContentLoaded",c,!1)):document.attachEvent&&(h=a,o=l.document,i=!1,(t=function(){try{o.documentElement.doScroll("left")}catch(l){return void setTimeout(t,50)}s()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,s())})}(window); ================================================ FILE: src/json/index.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-14 19:37:19 * @LastEditors: itab.link * @LastEditTime: 2022-01-12 20:52:45 * @Description: file content */ const videoList = [ { title: "格里姆瑟尔山口Totesee山地湖中倒映出的星星", local: "欧洲 瑞士 伯尔尼", src: "https://az3.sfo2.cdn.digitaloceanspaces.com/bingdesktop/3455b6778764415593fb5e688218fb89.mp4", }, ] const imgList = [{ title: "Loughrigg Tarn的日出", local: "欧洲 英国 英格兰湖区安布尔塞德", src: "https://tvax1.sinaimg.cn/large/007Tv3Vmly1gd0yldnd9ej31hc0u047i.jpg", }, { title: "黑暗中为你照明", local: "欧洲 波兰 希维诺乌伊希切", src: "https://tvax1.sinaimg.cn/large/bfe05ea9ly1fxgv3f6vjyj21hc0u07df.jpg", }, { title: "残阳夕照 落日余晖", local: "亚洲 越南 下龙湾", src: "https://tvax1.sinaimg.cn/large/bfe05ea9ly1fxgumr0a7mj21hc0u0k0j.jpg", }, { title: "", local: "", src: "https://wallpaper.infinitynewtab.com/wallpaper/3036.jpg", }, { title: "圣托里尼岛鸟瞰图", local: "欧洲 希腊", src: "https://tvax1.sinaimg.cn/large/007Tv3Vmly1gdlv1ubltej31hc0u0n67.jpg", }, { title: "南奥索峰的Lac d'Ayous小屋", local: "欧洲 法国", src: "https://tvax1.sinaimg.cn/large/007Tv3Vmly1getlalfp0hj31hc0u0dov.jpg", }, { title: "克林格尔农场的Mazezilla玉米田迷宫", local: "宾夕法尼亚州", src: "https://cn.bing.com//th?id=OHR.Mazezilla_ZH-CN8502282112_1920x1080.jpg&rf=LaDigue_1920x1080.jpg", }, ] // 0应用 1内置链接 2自定义链接 const navList = [{ type: 1, url: "", title: "天气", key: "weather", color: "#ffc303" }, { type: 1, url: "", title: "待办事项", key: "todo", color: "#409eff" }, { type: 1, url: "", title: "便笺", key: "note", color: "#fa8511" }, { type: 1, url: "", title: "设置", key: "setting", color: "#408ef0" }, // { type: 1, url: "", title: "快递查询", key: "kuaidi", color: "#e74c3c" }, { type: 0, url: "https://www.tmall.com", title: "天猫", key: "tmall", color: "#ff0030", }, { type: 0, url: "https://www.jd.com", title: "京东商城", key: "jd", color: "#d71912", }, { type: 0, url: "https://music.163.com/", title: "网易云音乐", key: "music163", color: "#f24452", }, { type: 0, url: "https://www.bilibili.com/", title: "bilibili", key: "bilibili", color: "#00b1ff", }, { type: 0, url: "http://iqiyi.com/", title: "爱奇艺", key: "iqiyi", color: "#08db02", }, { type: 0, url: "http://v.qq.com/", title: "腾讯视频", key: "vqq", color: "#ff8903", }, { type: 0, url: "https://weibo.com/", title: "微博", key: "weibo", color: "#e6162d", }, { type: 0, url: "https://www.zhihu.com/", title: "知乎", key: "zhihu", color: "#0084ff", }, { type: 0, url: "https://www.ctrip.com/", title: "携程", key: "ctrip", color: "#2377e2", }, { type: 0, url: "https://mail.qq.com/", title: "豆瓣", key: "douban", color: "#00b51d", }, { type: 0, url: "https://mail.qq.com/", title: "QQ邮箱", key: "email", color: "#f57f4f", }, { type: 1, url: '', title: "添加", key: "add", color: "#fa8511", } ].map((item, index) => { item.id = index return item }) export { videoList, imgList, navList } ================================================ FILE: src/main.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-10 18:03:48 * @LastEditors: www.itab.link * @LastEditTime: 2022-01-12 22:53:47 * @Description: file content */ import Vue from 'vue' import App from './App.vue' import directives from '@/utils/directives'; import filters from '@/utils/filters'; import local from '@/utils/localStrong'; import utils from '@/utils/utils'; import http from '@/api/index'; // import dModal from '@/components/public/d-modal'; import dTabs from '@/components/public/d-tabs'; import dIcon from '@/components/public/d-icon'; import '@/iconfont/iconfont.js' import '@/style/index.less' // store import store from '@/store/index'; // fade/zoom 等 import { Button, Row, Col, Switch, Image, Slider, Tooltip, Carousel, CarouselItem, Message, Checkbox, MessageBox, Dialog, Tabs, TabPane, Input, Form, FormItem, Loading, InfiniteScroll } from 'element-ui'; Dialog.props.closeOnPressEscape.default = false Dialog.props.closeOnClickModal.default = false Slider.props.showTooltip.default = false Dialog.props.appendToBody.default = true Vue.use(Button); Vue.use(Row); Vue.use(Col); Vue.use(Switch); Vue.use(Image); Vue.use(Slider); Vue.use(Tooltip); Vue.use(Carousel); Vue.use(CarouselItem); Vue.use(Checkbox); Vue.use(Dialog); Vue.use(Tabs); Vue.use(TabPane); Vue.use(Input); Vue.use(Form); Vue.use(FormItem); Vue.use(Loading); Vue.use(InfiniteScroll); Vue.prototype.$msgbox = MessageBox; Vue.prototype.$alert = MessageBox.alert; Vue.prototype.$confirm = MessageBox.confirm; Vue.prototype.$prompt = MessageBox.prompt; Vue.prototype.$notify = Notification; Vue.prototype.$message = Message; // 自定义组件 // Vue.component('dModal', dModal); Vue.component('dIcon', dIcon); Vue.component('dTabs', dTabs); // 添加过滤器 Object.keys(filters).forEach(key => Vue.filter(key, filters[key])) // 添加自定义指令 Object.keys(directives).forEach(key => Vue.directive(key, directives[key])) // 天气编码 const weatherIcon = { 100: 'qing', 101: 'yun', 102: 'yun', 103: 'yun', 104: 'yin', 150: 'qing-night', 153: 'yun-night', 154: 'yin', 300: 'shower', 301: 'shower', 302: 'thunder-shower', 303: 'thunder-shower', 304: 'thund-shower-hail', 305: 'rain1', 306: 'rain2', 307: 'rain3', 308: 'rain3', 309: 'rain1', 310: 'xiaobaoyu', 311: 'baoyu', 312: 'baoyu', 313: 'sleet', 400: 'snow1', 401: 'snow2', 402: 'snow3', 403: 'blizard', 404: 'sleet', 405: 'sleet', 406: 'sleet', 407: 'snow-shower', 500: 'wu', 501: 'wu', 502: 'haze', 503: 'sandstorm', 504: 'sandstorm', 507: 'sandstorm', 508: 'sandstorm', 509: 'wu', 510: 'wu', 511: 'haze', 512: 'haze', 513: 'haze', 514: 'wu' } Vue.config.productionTip = false Vue.prototype.$http = http Vue.prototype.$local = local Vue.prototype.$util = utils Vue.prototype.$weatherIcon = weatherIcon new Vue({ store, render: h => h(App), created() { this.$store.dispatch('initSetting') }, }).$mount('#app') ================================================ FILE: src/store/index.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-13 09:48:05 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-06-22 14:52:17 * @Description: file content */ import Vue from 'vue'; import Vuex from 'vuex'; import local from '@/utils/localStrong'; import dayjs from 'dayjs' import api from '@/api' import { Message } from 'element-ui' import { navList } from "@/json"; import utils from '../utils/utils'; function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod" ]; var flag = true; for (var v = 0; v < Agents.length; v++) { if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; } } return flag; } Vue.use(Vuex); // 保存 let saveConfig = (msg) => { let userInfo = local.get('userInfo') if (!userInfo) return // 走保存接口 let params = local.get('setContent') params.note = localStorage.getItem('note') params.id = localStorage.getItem('configId') params.navlist = localStorage.getItem('navList') params.todo = localStorage.getItem('todo') params.wallpaper = localStorage.getItem('wallpaper') api.configInfoSave(params).then(res => { if (!msg) return Message({ type: 'success', message: "手动备份成功", showClose: true }) }) } let debounceSaveConfig = (msg) => { let timer = true if (timer) { timer = false; saveConfig(msg) timer = setTimeout(() => { timer = true; }, 3000); } else { clearTimeout(timer) } } const setContent = { // 壁纸 bgBlur: 0, //背景进行模糊处理 themeMode: 'light', //主题模式 sunrise: false, //主题样式跟随日出日落 // 常规设置 iconSize: 82, //图标大小 iconRadius: 100, //图标半径 iconOpacity: 90, //图标透明度 iconTitle: true, //图标标题 startAnimation: true, //启动动画 layout: [2, 6], //图标布局 yiyan: true, //是否显示一言 search: 'baidu', //默认搜索 } export default new Vuex.Store({ state: { // 需要存储local setContent: setContent, //设置内容 wallpaper: {}, //壁纸 bingWallpaper: {}, //壁纸 navList: [], //导航图标列表 // 无需存储local editType: '', //编辑类型 add edit moment: '', //天气时刻 d白天 n晚上 note: [], weather: { now: {}, air_now_city: {}, sun: {} }, //实时天气 isShowSide: false, //是否显示侧边栏 sideComp: '', //侧边栏组件 navRowData: {}, //当前操作行数据 loginInfo: { visible: false, //是否显示dialog type: '', //是否显示dialog }, userInfo: null, }, getters: { }, mutations: { setSetContent(state, val) { state.setContent = val || setContent local.set("setContent", state.setContent); debounceSaveConfig() }, setWallpaper(state, val) { state.wallpaper = val local.set("wallpaper", val); debounceSaveConfig() }, setBingWallpaper(state, val) { state.bingWallpaper = val local.set("bingWallpaper", val); }, setNavList(state, val) { state.navList = val local.set("navList", val); debounceSaveConfig() }, setMoment(state, val) { state.moment = val local.set("moment", val); }, setNote(state, val) { state.note = val local.set("note", val); debounceSaveConfig() }, setWeather(state, val) { state.weather = val }, setShowSide(state, obj) { state.isShowSide = obj.val if (obj.comp) { state.sideComp = obj.comp } if (obj.editType) { state.editType = obj.editType } }, setNavRowData(state, val) { state.navRowData = val }, setLoginInfo(state, val) { state.loginInfo = val }, setUserInfo(state, val) { local.set("userInfo", val); state.userInfo = val }, }, actions: { // 保存配置 async saveConfig() { debounceSaveConfig(true) }, // 初始化 async initSetting(context) { // if (IsPC()) { // setContent.iconSize = 70 // setContent.layout = [2, 5] // } let userInfo = local.get('userInfo') const state = context.state state.wallpaper = local.get('wallpaper') || '' state.userInfo = userInfo || {} state.setContent = local.get('setContent') || setContent state.navList = local.get('navList') || utils.deepClone(navList) state.bingWallpaper = local.get('bingWallpaper') state.note = local.get('note') || [{ text: "", created: dayjs().valueOf(), },] // 如果token过期 或者没有登陆 不走接口 if (!userInfo) return let res = await api.configInfoCurInfo() let data = res.data || {} if (res.code == 200) { // 如果id==0此账号没有被保存过 if (data.id == 0) { // 走保存接口 let params = local.get('setContent') params.note = localStorage.getItem('note') params.navlist = localStorage.getItem('navList') params.todo = localStorage.getItem('todo') params.wallpaper = localStorage.getItem('wallpaper') let res = await api.configInfoSave(params) } else { //保存configID 用于更新配置 local.set('configId', data.id) state.setContent = data || setContent state.navList = data.navlist ? JSON.parse(data.navlist) : utils.deepClone(navList) state.wallpaper = JSON.parse(data.wallpaper) || {} state.todo = JSON.parse(data.todo) || {} state.note = JSON.parse(data.note) || [{ text: "", created: dayjs().valueOf(), },] } } Object.keys(setContent).forEach(key => { if (state.setContent[key] == undefined) { // 如果local里没有 当前项 那么设置成默认 state.setContent[key] = setContent[key] } }) } }, }) ================================================ FILE: src/style/animate.less ================================================ .zoomIn { animation: zoomIn ease 0.4s; transform-origin: center 50px; // transition: 0.2s; } .fadeIn { animation: fadeIn ease 0.5s; transform-origin: center 50px; // transition: 0.2s; } .swing { animation: aswing ease 0.3s infinite; transform-origin: center 50px; } .scaleOut { animation: scaleOut ease 0.2s; } .rotateIn { animation: rotateIn ease 0.2s; } .leftOut { animation: leftOut ease-in-out 0.2s; } .zoomOut { animation: zoomOut ease-in-out 0.2s; } @keyframes zoomOut { from { opacity: 1; } 50% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } to { opacity: 0; } } @keyframes zoomIn { from { opacity: 0; transform: scale3d(.1, .1, .1); } 50% { opacity: 1; } } @keyframes leftOut { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(-2000px, 0, 0); transform: translate3d(-2000px, 0, 0); } } @keyframes rotateIn { from { width: 0; opacity: 0; transform: rotate(360deg); } 50% { opacity: 1; } } @keyframes aswing { 0% { transform: rotate(0) scale(1) } 20% { transform: rotate(-2deg) scale(1) } 60% { transform: rotate(0) scale(1) } 80% { transform: rotate(2deg) scale(1) } 100% { transform: rotate(0) scale(1) } } @keyframes scaleOut { from { transform-origin: center; opacity: 1; } to { width: 0; transform-origin: center; transform: scale(0); opacity: 0; } } // transition 动画 .el-fade-in-enter-active, .el-fade-in-leave-active { transition: all .3s cubic-bezier(.55, 0, .1, 1); } .el-fade-in-enter, .el-fade-in-leave-active { opacity: 0; } .is-animating { transition: transform 580ms cubic-bezier(.41, 1.5, 0.5, 1) 0s !important; } ================================================ FILE: src/style/base.less ================================================ /*字体*/ .b { font-weight: bold; } .n { font-weight: normal; } // font-size:12px - 50px // @for $i from 12 through 50 { // .f#{$i} { // font-size: $i+px; // } // } .fontLoop(@n, ) when (@n =< 50) { .f@{n} { font-size: (0px + @n) } .fontLoop(@n+1); } .fontLoop(12); /*边距*/ // margin:0px - 50px .mLoop(@n, ) when (@n =< 50) { // margin:0px - 50px .m@{n} { margin: (0px + @n) } // margin-top:0px - 50px .mt@{n} { margin-top: (0px + @n) } // margin-bottom:0px - 50px .mb@{n} { margin-bottom: (0px + @n) } // margin-left:0px - 50px .ml@{n} { margin-left: (0px + @n) } // margin-right:0px - 50px .mr@{n} { margin-right: (0px + @n) } // padding:0px - 50px .p@{n} { padding: (0px + @n) } // padding-top:0px - 50px .pt@{n} { padding-top: (0px + @n) } // padding-bottom:0px - 50px .pb@{n} { padding-bottom: (0px + @n) } // padding-left:0px - 50px .pl@{n} { padding-left: (0px + @n) } // padding-right:0px - 50px .pr@{n} { padding-right: (0px + @n) } .mLoop(@n+5); } .mLoop(0); // 表单高度 一般用于弹出框 el-form 上面 .d-form-y { max-height: calc(100vh - 140px); overflow-y: auto; } /*布局*/ .d-main { min-width: 1200px; } .d-relative { position: relative; } .d-absolute { position: absolute; } .d-fixed { position: fixed; } /*浮动*/ .fl { float: left; } .fr { float: right } /*对齐*/ .al { text-align: left; } .ac { text-align: center; } .ar { text-align: right; } /*辅助*/ .d-nowrap { white-space: nowrap; } .d-elip { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } .d-disabled { background: #e8e8e8; color: #999; cursor: not-allowed } .d-pointer { cursor: pointer; } .d-show { display: block; } .d-hide { display: none; } .d-hidden { overflow: hidden; } .d-auto-x { overflow-x: auto; } .d-auto-y { overflow-y: auto; } .d-fieldset { border: 1px solid #d3dce6; border-radius: 2px; } .d-block { display: block; } .d-inline { display: inline-block; } .d-middle { vertical-align: middle; } .d-box { box-sizing: border-box; } .d-clear { clear: both; } /*高度*/ .hfull { height: 100%; } /*宽度*/ .wfull { width: 100% } /* 边框 */ .bt { border-top: 1px solid #dcdfe6; } .bb { border-bottom: 1px solid #dcdfe6; } .bl { border-left: 1px solid #dcdfe6; } .br { border-right: 1px solid #dcdfe6; } .ba { border: 1px solid #dcdfe6; } .bn { border: none; } /*背景色*/ .d-bg-gray { background: #f2f2f2; } /*灰色*/ .d-bg-qgray { background: #999; } /*灰色*/ .d-bg-white { background: #fff; } /*白色*/ .d-bg-black { background: #aaa; color: #fff } /*黑色*/ .d-bg-red { background: #ff0000; color: #fff } /*h*/ .d-bg-pink { background: #ff6969; color: #fff; } /*粉红主色*/ .d-bg-violet { background: #9965cc; color: #fff; } /*紫色*/ .d-bg-brown { background: #f1a85f; color: #fff; } /*棕色*/ .d-bg-crimson { background: #ac0222; color: #fff; } /*赤红*/ .d-bg-cyan { background: #33ba9b; color: #fff; } /*青色*/ .d-bg-blue { background: #189eff; color: #fff; } /*蓝色*/ .d-bg-green { background: #67c23a; color: #fff; } /*绿色*/ .d-bg-orange { background: #ff9906; color: #fff; } /*橙色*/ .d-bg-yellow { background: #E6A23C; color: #fff; } /*橙色*/ /*字体颜色*/ .d-text-pink { color: #ff6969; } /*粉红主色*/ .d-text-red { color: #ff0000 !important; } /*红色*/ .d-text-tred { color: #F56C6C; } /*A/特级红*/ .d-text-violet { color: #9965cc; } /*紫色*/ .d-text-brown { color: #f1a85f; } /*棕色*/ .d-text-gold { color: #ecda42 } .d-text-crimson { color: #ac0222; } /*赤红*/ .d-text-cyan { color: #33ba9b; } /*青色*/ .d-text-blue { color: #189eff; } /*蓝色*/ .d-text-green { color: #67c23a; } /*绿色*/ .d-text-orange { color: #ff9906; } /*橙色*/ .d-text-gray { color: #666; } /*灰色*/ .d-text-qgray { color: #999; } /*灰色*/ .d-text-white { color: #fff; } /*白色*/ .d-text-black { color: #333; } /*黑色*/ /*布局*/ .d-flex { display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ */ display: -moz-box; /* Firefox 17- */ display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */ display: -moz-flex; /* Firefox 18+ */ display: -ms-flexbox; /* IE 10 */ display: flex; } .d-flex-center { display: flex; flex-flow: wrap; align-items: center; justify-content: center } /* 水平居中 */ .d-flex-hor { display: flex; justify-content: center } /* 垂直居中 */ .d-flex-ver { display: flex; align-items: center; } /* 分部两边 */ .d-flex-between { display: flex; align-items: center; justify-content: space-between; } .d-cell { flex: 1 } .d-shrink { flex-shrink: 1; } /* 水平垂直居中 */ ================================================ FILE: src/style/common.less ================================================ // slide显示样式 .range-slider__value { line-height: 20px; font-size: 13px; position: relative; display: inline-block; width: 40px; margin-left: 4%; padding: 4px 6px; text-align: center; color: #fff; border-radius: 3px; background: var(--primary-color); &:after { position: absolute; top: 7px; left: -6px; width: 0; height: 0; content: ''; border-top: 7px solid transparent; border-right: 7px solid var(--primary-color); border-bottom: 7px solid transparent; } } ================================================ FILE: src/style/element.less ================================================ .el-message-box, .el-dialog { background-color: var(--background-info); border-color: var(--background-info); } .el-message-box__title, .el-dialog__title { color: rgba(var(--main-color), 0.7); } .el-message-box__content, .el-dialog__body { padding: 10px 20px; color: rgba(var(--main-color), 0.6); } .el-dialog__body { max-height: calc(100vh - 107px); overflow: auto; } .el-input__inner { background-color: rgba(var(--main-color), 0.08); border-color: rgba(var(--main-color), 0.08); color: rgba(var(--main-color), .8); } .el-form-item__label { color: rgba(var(--main-color), .8); } .el-form-item { margin-bottom: 15px; } ================================================ FILE: src/style/index.less ================================================ @import './theme.less'; @import './base.less'; // @import './normalize.less'; 重置的属性太少 暂时不用 @import './reset.less'; @import './common.less'; @import './animate.less'; @import './element.less'; ================================================ FILE: src/style/reset.less ================================================ /* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { box-sizing: border-box; margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } table { border-collapse: collapse; border-spacing: 0; } a { text-decoration: none; } input, textarea { outline: none; border: none; background-color: transparent; font-family: 'PingFang SC', 'Microsoft Yahei', Helvetica, Arial, sans-serif; } * { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } input, textarea { -webkit-user-select: auto; } html { font-family: 'PingFang SC', 'Microsoft Yahei', Helvetica, Arial, sans-serif; font-size: 16px; word-spacing: 1px; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; box-sizing: border-box; } html, body { scroll-behavior: smooth; height: 100%; width: 100%; } // 隐藏滚动条样式 .i-scrollbar-hide { &::-webkit-scrollbar { width: 0; height: 3px; } &::-webkit-scrollbar-track { background-color: transparent; } &::-webkit-scrollbar-thumb { background: #e8eaec; } } // 极简滚动条样式 &::-webkit-scrollbar { width: 6px; height: 1px; } &::-webkit-scrollbar-track { background-color: transparent; } &::-webkit-scrollbar-thumb { background: #808695; border-radius: 4px; } ================================================ FILE: src/style/theme.less ================================================ // 深色模式 .dark { // 背景 --background: 0, 0, 0; --background-info: #1e1e1e; --main-color: 255, 255, 255; } // 亮色模式 .light { --background: 255, 255, 255; --background-info: #fff; --main-color: 0, 0, 0; } :root { --primary-color: #409eff; } ================================================ FILE: src/utils/directives.js ================================================ /* * @Author: web.王晓冬 * @Date: 2019-08-01 11:54:35 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-27 14:31:18 * @Description: 自定义指令 directive * @axample: */ let unit = (val) => { if (typeof val == "string") { return val } else { return val + 'px' } } export default { // 高度 用于style里的widht设置 string,number# w: { inserted(el, binding) { if (binding.value) { el.style.width = unit(binding.value) } }, update(el, binding) { if (binding.value) { el.style.width = unit(binding.value) } }, unbind(el) { el.style.width = null; } }, //end // 高度 用于style里的height设置 string,number# h: { inserted(el, binding) { if (binding.value) { el.style.height = unit(binding.value) } }, update(el, binding) { if (binding.value) { el.style.height = unit(binding.value) } }, unbind(el) { el.style.height = null; } }, //end padding: { inserted(el, binding) { if (binding.value) { el.style.padding = binding.value + unit(binding.value); } }, update(el, binding) { if (binding.value) { el.style.padding = binding.value + unit(binding.value); } }, unbind(el) { el.style.padding = null; } }, font: { inserted(el, binding) { if (binding && binding.value) { el.style.fontSize = `${binding.value}px`; } }, update(el, binding) { if (binding && binding.value) { el.style.fontSize = `${binding.value}px`; } }, unbind(el) { el.style.fontSize = null; } }, color: { inserted(el, binding) { if (binding.value) { el.style.color = binding.value; } }, update(el, binding) { if (binding.value) { el.style.color = binding.value; } }, unbind(el) { el.style.color = null; } }, bgColor: { inserted(el, binding) { if (binding.value) { el.style.backgroundColor = binding.value; } }, update(el, binding) { if (binding.value) { el.style.backgroundColor = binding.value; } }, unbind(el) { el.style.backgroundColor = null; } }, // size size: { inserted: function (el, binding) { el.style.height = unit(binding.value) el.style.width = unit(binding.value) }, update: function (el, binding) { el.style.height = unit(binding.value) el.style.width = unit(binding.value) } }, //end // size lh: { inserted: function (el, binding) { el.style.lineHeight = unit(binding.value) }, update: function (el, binding) { el.style.lineHeight = unit(binding.value) } }, //end // size focus: { inserted: function (el, binding) { if (binding.value) { // 聚焦元素 el.focus() } } }, //end // click 时间防抖 一般用于 保存按钮 {Number=1000} 毫秒# debounce: { inserted(el, binding) { let duration = binding.value || 1000 el.addEventListener('click', e => { if (!el.disabled) { el.disabled = true let timer = setTimeout(() => { el.disabled = false timer = null }, duration) } }) } }, //end } ================================================ FILE: src/utils/filters.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-27 09:19:18 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-10-30 17:47:15 * @Description: file content */ import dayjs from 'dayjs' export default { /** * @desc 时间戳转字符串 使用的是mement.js * @default YYYY-MM-DD # */ timeToStr(value, formatString = 'YYYY-MM-DD') { if (typeof value !== 'number') { return ''; } return dayjs(value).format(formatString); }, //end } ================================================ FILE: src/utils/localStrong.js ================================================ /* * @Author: web.王晓冬 * @Date: 2018年7月10日 17:56:26 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-08-14 15:54:55 * @Description: localStorage操作 * @axample //存储用户信息 this.$local.set('userInfo', { name: 'wxd' }) //获取用户信息 let userInfo = this.$local.get('userInfo') */ const local = { // 保存数据 params: 1:key 2:value # set(key = '', value = '') { localStorage.setItem(key, JSON.stringify(value)) },//end // 获取数据 params: 1:key# get(key = null) { return JSON.parse(localStorage.getItem(key) || null) || '' },//end // 清空localStrong # clear() { localStorage.clear() },//end // 移除localStrong某一项 params: 1:key# remove(key = '') { return localStorage.removeItem(key) } } export default local ================================================ FILE: src/utils/utils.js ================================================ /* * @Author: web.王晓冬 * @Date: 2019-10-15 10:28:51 * @LastEditors: web.王晓冬 * @LastEditTime: 2020-12-07 18:08:09 * @Description: 公共方法 * @axample //深度拷贝对象 let obj = {a:{a:1}} let newObj = this.$util.deepClone(obj) */ const utils = { // 判断是否是空对象 {Object}# isEmptyObject(obj) { for (const name in obj) { return false; } return true; }, //end // 判断是否是window对象 {ele}# isWindow(obj) { return obj != null && obj === obj.window; }, //end // 判断数据类型{x} # type(obj) { const class2type = {}; 'Boolean Number String Function Array Date RegExp Object Error'.split(' ').map((item, index) => { class2type[`[object ${item}]`] = item.toLowerCase(); }); if (obj == null) { return `${obj}`; } return typeof obj === 'object' || typeof obj === 'function' ? class2type[Object.prototype .toString.call(obj)] || 'object' : typeof obj; }, //end // 判断是不是 DOM 元素 {Dom}# isElement(obj) { return !!(obj && obj.nodeType === 1); }, //end // 对象/数组数据深拷贝 {Object}# deepClone(source) { if (!source && typeof source !== 'object') { throw new Error('error arguments', 'deepClone') } const targetObj = source.constructor === Array ? [] : {} Object.keys(source).forEach(keys => { if (source[keys] && typeof source[keys] === 'object') { targetObj[keys] = utils.deepClone(source[keys]) } else { targetObj[keys] = source[keys] } }) return targetObj }, //end // HTML格式转换成文本 {Html}# html2Text(val) { const div = document.createElement('div') div.innerHTML = val return div.textContent || div.innerText }, //end // 数组去重 {Array}# uniqueArr(arr) { return Array.from(new Set(arr)) }, //end // 创建唯一字符串 {String} # createUniqueString() { const timestamp = +new Date() + '' const randomNum = parseInt((1 + Math.random()) * 65536) + '' return (+(randomNum + timestamp)).toString(32) }, //end // 事件防抖 {fn} {Number =1000} # debounce(fn, delay = 1000) { let timer = null return () => { if (timer) { clearTimeout(timer) } timer = setTimeout(fn, delay) // 简化写法 } }, }; export default utils; ================================================ FILE: src/views/home.vue ================================================ /* * @Author: web.王晓冬 * @Date: 2020-10-10 18:08:41 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-03-22 15:01:50 * @Description: file content */ ================================================ FILE: vue.config.js ================================================ /* * @Author: web.王晓冬 * @Date: 2020-03-25 14:14:18 * @LastEditors: web.王晓冬 * @LastEditTime: 2021-06-10 14:02:34 * @Description: file content */ module.exports = { devServer: { host: "0.0.0.0", port: 8088, // 端口号 https: false, // https:{type:Boolean} open: true, //配置自动启动浏览器 proxy: { "/apis": { target: "http://106.75.136.242:8088/", // 本地 changeOrigin: true, pathRewrite: { '^/apis': '' } }, }, }, // 构建输入文件夹 outputDir: process.env.NODE_ENV == 'web' ? 'search' : 'newTabs/dist', css: { // 是否使用css扩展 requireModuleExtension: true, // loaderOptions: { // 向 CSS 相关的 loader 传递选项 // less: { // javascriptEnabled: true // } // } }, productionSourceMap: false, // publicPath: process.env.NODE_ENV === 'production' ? // '../' : './', // publicPath: process.env.NODE_ENV === 'production' ? '../search' : './', publicPath: './', // configureWebpack: { // externals: { // 'vue': 'Vue', // 'vuex': 'Vuex', // 'vue-router': 'VueRouter', // 'element-ui': 'ELEMENT', // 'axios': 'axios' // } // } runtimeCompiler: true, }