import { Injectable } from '@angular/core'; import { NzMessageService } from 'ng-zorro-antd/message'; import { NzNotificationService } from 'ng-zorro-antd/notification'; import { Router, ActivatedRoute } from "@angular/router"; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class EmopUtilsService { /** * token */ access_token = ''; constructor( private nzNotificationService: NzNotificationService, private nzMessageService: NzMessageService, private router: Router, private route: ActivatedRoute, private http: HttpClient ) { } /** * 初始化开发模式的组件库 */ init(options?: { access_token?: string; }) { console.log('%c当前使用公用组件库版本: %cv@VERSION@', 'color: blue;', 'color: green;'); // 开发环境时自动设置token options.access_token && this.setToken(options.access_token); } /** * 初始化开发模式的组件库 */ // initCli(options?: { // access_token: string; // }) { // if (environment.production) return; // console.log('%c当前使用公用组件库版本: %cv@VERSION@', 'color: blue;', 'color: green;'); // // 开发环境时自动设置token // options.access_token && this.setToken(options.access_token); // } private setToken(access_token: string) { document.cookie = "access_token=" + access_token; this.emopLog('开发环境初始化token成功,如需要更改token请在init函数中修改options值'); } private emopLog(value: string) { console.log('%cEmop-components-angular开发脚手架%c' + value, 'color:#fff; padding: 2px 6px; background: skyblue;border-radius: 3px;margin-right: 3px;', 'color: green'); } /** * 创建全局提示框 * @param type 消息提示类型 'success' | 'error' | 'info' | 'warning' | 'loading' * @param title 消息提示标题 */ message(type: 'success' | 'error' | 'info' | 'warning' | 'loading', title) { this.nzMessageService[type](title, { nzDuration: 2000 }); } /** * 创建通知提醒框 * @param type 类型 'success' | 'info' | 'warning' | 'error' * @param title 标题 * @param content 内容 */ notice(type: 'success' | 'info' | 'warning' | 'error', title, content?) { this.nzNotificationService[type]( title, content, { nzDuration: 2000 } ); } /** * 拖拽 * @param selector 要被拖拽的元素 仅支持css选择器 * @param moveSelector 可选 被移动的元素 仅支持css选择器 * @returns */ drag(selector, moveSelector = null) { const target = document.querySelector(selector); let moveTarget; if (moveSelector) moveTarget = document.querySelector(moveSelector); if (!target) return console.error('拖拽库调用失败:找不到该选择器'); target.style.cursor = 'move'; let listenData = { state: 'static', offsetX: 0, offsetY: 0, selectedNode: moveTarget || target, parentNode: null }; target.addEventListener('mousedown', (e) => { listenData.state = 'moving'; listenData.offsetX = e['clientX'] - listenData.selectedNode.offsetLeft; listenData.offsetY = e['clientY'] - listenData.selectedNode.offsetTop; }); document.addEventListener('mousemove', (e) => { if (listenData.state === 'moving') { let moveX = e['clientX'] - listenData.offsetX; let moveY = e['clientY'] - listenData.offsetY; moveX = moveX < 0 ? 0 : moveX > innerWidth - listenData.selectedNode['clientWidth'] ? innerWidth - listenData.selectedNode['clientWidth'] : moveX; moveY = moveY < 0 ? 0 : moveY > innerHeight - listenData.selectedNode['clientHeight'] ? innerHeight - listenData.selectedNode['clientHeight'] : moveY; listenData.selectedNode['style'].left = moveX + 'px'; listenData.selectedNode['style'].top = moveY + 'px'; } }); document.addEventListener('mouseup', (e) => { listenData.state = 'static'; }); document.addEventListener('mouseleave', (e) => { listenData.state = 'static'; }); } /** * 路由跳转 * @param url 跳转的路由地址 * @param queryParams 跳转携带的参数 */ navigate(url: string, queryParams?) { this.router.navigate([url], { queryParams, }); } /** * uuid 生成 */ // static getUUID = () => { // return v4(); // }; // static getUUID() { // return "xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => { // const r = (Math.random() * 16) | 0; // const v = c === "x" ? r : (r & 0x3) | 0x8; // return v.toString(16); // }); // }; /** * 获取路由中携带的get参数 * @returns 返回get参数对象 */ getRouteQueryParams() { return this.route.snapshot.queryParams; } /** * 处理api回调的响应函数 * @param res 服务器响应的数据 * @param successFn 响应200的回调 * @param errorFn 响应不是200的回调 */ response(res, successFn: Function, errorFn?: Function) { if (res.status === 200) { successFn(res); } else { if (errorFn) { errorFn(res); } else { this.message('error', res.message); } } } /** * 清除登录信息 */ logout() { sessionStorage.clear(); localStorage.clear(); document.cookie = 'access_token='; this.http.post(`/gateway/tc/logout`, null).subscribe(() => { window.location.href = `/gateway/static/index.html#/login?redirect=${encodeURI(window.location.pathname + window.location.hash)}`; }); } /** * 将内容复制进剪贴板 */ copy(text: string): boolean { let textareaEl = document.createElement('textarea'); textareaEl.setAttribute('readonly', 'readonly'); textareaEl.value = text; document.body.appendChild(textareaEl); textareaEl.select(); let res = document.execCommand('copy'); document.body.removeChild(textareaEl); return res; } /** * 将类似get参数的字符串解析成对象 */ parseCookie() { let result = {}; let arr = document.cookie.split('; '); arr.forEach(item => { let tempArray = item.split('='); result[tempArray[0]] = tempArray[1]; }); return result; } } export function Rest(url: string) { return (target) => { target.$baseUrl = url; }; } /** * 请求的装饰器 * @param url 请求的地址 * 被装饰的函数中第一个参数是传参数据,get请求会自动拼接在url中,post请求会在请求体中。第二个参数是路径参数,会自动拼接在url中。 */ export function Get(url: string) { return baseRequest('get', url); } /** * 请求的装饰器 * @param url 请求的地址 * 被装饰的函数中第一个参数是传参数据,get请求会自动拼接在url中,post请求会在请求体中。第二个参数是路径参数,会自动拼接在url中。 */ export function Post(url: string) { return baseRequest('post', url); } /** * 请求的装饰器 * @param url 请求的地址 * 被装饰的函数中第一个参数是传参数据,get请求会自动拼接在url中,post请求会在请求体中。第二个参数是路径参数,会自动拼接在url中。 */ export function Put(url: string) { return baseRequest('put', url); } /** * 请求的装饰器 * @param url 请求的地址 * 被装饰的函数中第一个参数是传参数据,get请求会自动拼接在url中,post请求会在请求体中。第二个参数是路径参数,会自动拼接在url中。 */ export function Delete(url: string) { return baseRequest('delete', url); } /** * 基础请求方法 * @param method 请求方式 * @param url 请求地址 * @returns */ function baseRequest(method: string, url: string) { return function (target, name, descriptor) { const oldValue = descriptor.value; descriptor.value = function (...args) { // 当需要加入路径参数时,对应处理 // 1. 获取该函数内 参数/值的对象 const paramsObj = getParameterObject(getParameterName(oldValue), [...args]); // 2. 处理路径参数 url = patchPathUrl(url, paramsObj); // 3. 查找HttpClient服务,调用 for (const key in this) { if (this[key] instanceof HttpClient) { return this[key][method]( target.constructor.$baseUrl ? target.constructor.$baseUrl + url : url, method === 'get' ? { params: paramsObj['params'] } : paramsObj['data'], method !== 'get' && { params: paramsObj['params'] } ); } } }; }; } /** * 获取函数的参数对象 */ export function getParameterObject(keys, values) { let resultObj = {}; keys.forEach((item, index) => { resultObj[item] = values[index]; }); return resultObj; } /** * 获得函数的所有参数名 * @param fn 函数 * @returns */ export function getParameterName(fn: Function) { if (typeof fn !== 'object' && typeof fn !== 'function') return; const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; const DEFAULT_PARAMS = /=[^,)]+/mg; const FAT_ARROWS = /=>.*$/mg; let code = fn.prototype ? fn.prototype.constructor.toString() : fn.toString(); code = code .replace(COMMENTS, '') .replace(FAT_ARROWS, '') .replace(DEFAULT_PARAMS, ''); let result = code.slice(code.indexOf('(') + 1, code.indexOf(')')).match(/([^\s,]+)/g); return result === null ? [] : result; } /** * 当需要加入路径参数时,对应处理 * @param url 路径数据 * @param paramsObj 待翻译的字典对象 */ function patchPathUrl(url: string, pathParamsArray: object): string { let matchArray; while (matchArray = /\${(.+?)\}/.exec(url)) { if (matchArray && pathParamsArray['pathParams']) { url = url.replace(matchArray[0], pathParamsArray['pathParams'][matchArray[1]]); } else { url = url.replace(matchArray[0], ''); console.error('检测到模板路径,请传入模板参数pathParams并在内部提供对应的字段'); } } return url; }