utils.js 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896
  1. import moment from 'moment';
  2. import React, { Component, Fragment } from 'react';
  3. import nzh from 'nzh/cn';
  4. import router from 'umi/router';
  5. import { getMenuMatches } from '@/components/SiderMenu/BaseMenu';
  6. import Link from 'umi/link';
  7. import ALibbSvg from '@/components/ALibbSvg';
  8. import { parse, stringify } from 'qs';
  9. import styles from '../global.less';
  10. import { message, Popconfirm, Input, notification, Icon, Tooltip, Popover } from 'antd';
  11. import { apiUrl, uploadLimit, sldStatShowDebug } from './sldconfig.js';
  12. import { formatMessage } from 'umi/locale';
  13. import request from './request';
  14. import fetch from 'dva/fetch';
  15. import { getLocale } from 'umi/locale';
  16. import defaultSettings from '@/defaultSettings';
  17. import isEmpty from "lodash/isEmpty"
  18. const Search = Input.Search;
  19. export const menu_second_color = [defaultSettings.primaryColor, defaultSettings.primaryLightColor];//一级菜单页面图标的颜色
  20. export const menu_second_default_icon = 'tiaoboleixing';//一级菜单页面默认的图标
  21. export const menu_second_icon_marginT = 12;//一级菜单页面图标距离左边的距离
  22. export const sld_ueditor_url = `${apiUrl}ueditor/index.html`;//ueditor的地址
  23. //统一配置
  24. export const commonSetting = {
  25. 'operateTipSwitch': true,//页面操作提示开关
  26. 'specLimit': 3,//发布商品——每个商品最多添加3个规格项
  27. 'specValLimit': 10,//发布商品——每个规格项最多添加10个规格值
  28. };
  29. export function sldSvgIcon(svgColor, svgW, svgH, svg) {
  30. return <ALibbSvg fill={svgColor} width={svgW} height={svgH} type={svg}/>;
  31. }
  32. /*
  33. * 表格分页数据统一
  34. * @param {object} pagination 分页数据对象
  35. * @param {object} filtersArg 表格列的过滤数据
  36. * @param {object} sorter 表格列的筛选数据
  37. * @param {object} formValues 搜索数据
  38. * */
  39. export function sldHandlePaginationData(pagination, filtersArg, sorter, formValues = {}) {
  40. const filters = Object.keys(filtersArg).reduce((obj, key) => {
  41. const newObj = { ...obj };
  42. newObj[key] = getValue(filtersArg[key]);
  43. return newObj;
  44. }, {});
  45. const params = {
  46. current: pagination.current,
  47. pageSize: pagination.pageSize,
  48. ...formValues,
  49. ...filters,
  50. };
  51. if (sorter.field) {
  52. params.sorter = `${sorter.field}_${sorter.order}`;
  53. }
  54. return params;
  55. }
  56. /*
  57. * 表格分页数据统一(只用于统计的报表模块)
  58. * @param {object} pagination 分页数据对象
  59. * @param {object} filtersArg 表格列的过滤数据
  60. * @param {object} sorter 表格列的筛选数据
  61. * @param {object} formValues 搜索数据
  62. * @param {number} type 1为sort字段为驼峰形式,2为sort字段为下划线连接
  63. * */
  64. export function sldHandlePaginationDataStat(pagination, filtersArg, sorter, formValues = {}, type = 1, pageSize) {
  65. const filters = Object.keys(filtersArg).reduce((obj, key) => {
  66. const newObj = { ...obj };
  67. newObj[key] = getValue(filtersArg[key]);
  68. return newObj;
  69. }, {});
  70. const params = {
  71. current: pagination.current || 1,
  72. pageSize: pagination.pageSize || pageSize,
  73. ...formValues,
  74. ...filters,
  75. };
  76. //升序、降序的处理
  77. if (sorter.order) {
  78. if (sorter.order == 'ascend') {
  79. params.type = 'asc';
  80. } else if (sorter.order == 'descend') {
  81. params.type = 'desc';
  82. }
  83. }
  84. if (sorter.field) {
  85. if (type == 1) {
  86. //sort字段为驼峰形式
  87. params.sort = sorter.field;
  88. } else if (type == 2) {
  89. //sort字段为下划线连接
  90. params.sort = sldConvert(sorter.field);
  91. }
  92. }
  93. return params;
  94. }
  95. /*
  96. * 驼峰形式的字符串转为下划线连接
  97. * @param {int} index 第几列
  98. * @param {int} size 宽度值
  99. * @param {array} columns_data table的columns数据
  100. * */
  101. export function sldConvert(str) {
  102. let target = '';
  103. let strArray = str.split('');
  104. strArray.map(item => {
  105. if (item === item.toUpperCase()) {
  106. target += `_${item.toLowerCase()}`;
  107. } else {
  108. target += item;
  109. }
  110. });
  111. return target;
  112. }
  113. /*
  114. * 表格拖动更新每列的宽度
  115. * @param {int} index 第几列
  116. * @param {int} size 宽度值
  117. * @param {array} columns_data table的columns数据
  118. * */
  119. export function dragSldTableColumn(index, size, columns_data) {
  120. let nextColumns = [...columns_data];
  121. nextColumns[index] = {
  122. ...nextColumns[index],
  123. width: size.width,
  124. };
  125. return nextColumns;
  126. }
  127. //判断数据是否是空对象
  128. export function isEmptyObject(data) {
  129. if (Object.getOwnPropertyNames(data).length === 0) {
  130. return true;//空对象
  131. } else {
  132. return false;//非空对象
  133. }
  134. }
  135. export function fixedZero(val) {
  136. return val * 1 < 10 ? `0${val}` : val;
  137. }
  138. //将数字转为字符串
  139. export function numExcString(text) {
  140. return text.toString();
  141. }
  142. //如果为null的话返回空字符串
  143. export function isNullExcString(text) {
  144. return text == null ? '' : text;
  145. }
  146. //设置用户登录有效期缓存时间
  147. export function setLocalStorageTime() {
  148. localStorage.setItem('time', new Date().getTime());
  149. }
  150. //获取缓存的值——json类型
  151. export function getLocalStorageJsonVal(key) {
  152. let val = localStorage.getItem(key);
  153. return JSON.parse(val);
  154. }
  155. /*
  156. * 获取缓存的值——String类型
  157. * 返回值字符串 有值返回具体的值,否则返回空字符串
  158. * @zjf-2020-11-26
  159. * */
  160. export function getLocalStorageStingVal(key) {
  161. let val = localStorage.getItem(key);
  162. return val != undefined && val != null && val ? val : '';
  163. }
  164. //获取三级缓存地址
  165. export function getSldArea() {
  166. return JSON.parse(localStorage.getItem('common_area_list'));
  167. }
  168. //高度填充
  169. export function getSldEmptyH(sldHeight, bg = '#fff') {
  170. return <div style={{ width: '100%', height: sldHeight, background: bg }}></div>;
  171. }
  172. //宽度填充
  173. export function getSldEmptyW(sldWidth) {
  174. return <div style={{ height: '100%', width: sldWidth }}></div>;
  175. }
  176. //获取用户缓存
  177. export function getSldToken() {
  178. return localStorage.getItem('sld_token');
  179. }
  180. //退出登陆
  181. export async function loginOut() {
  182. //跳转登录页
  183. let des_url = window.location.href;
  184. if (des_url.indexOf('redirect=') != -1) {
  185. des_url = des_url.substring(0, des_url.indexOf('redirect=') - 1);
  186. }
  187. await requestLogout();//调用退出登录的接口
  188. //清除全部缓存
  189. localStorage.clear();
  190. router.replace('/user/login?redirect=' + encodeURIComponent(des_url));
  191. window.location.reload();
  192. }
  193. //调用退出登录的接口
  194. async function requestLogout() {
  195. let sld_refresh_token = localStorage.getItem('sld_refresh_token');
  196. let param = new FormData();
  197. param.append('grant_type', 'refresh_token');
  198. param.append('refresh_token', sld_refresh_token);
  199. await fetch(apiUrl + 'v3/adminLogin/oauth/logout', {
  200. credentials: 'include',
  201. headers: {
  202. Authorization: 'Basic VVcxS2FsRlhVblJoVnpROTpVMjFHTWxsVlFrUmlNMEkxVlcxc2JtRklVa0ZWTW5oMldrYzVkUT09',
  203. },
  204. method: 'POST',
  205. body: param,
  206. }).then(response => response.json());
  207. }
  208. //验证手机号
  209. export function sldCheckMobile(s) {
  210. if (mobile_reg.test(s)) {
  211. return true;
  212. } else {
  213. return false;
  214. }
  215. }
  216. //验证邮箱
  217. export function sldCheckEmail(s) {
  218. let regu = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
  219. let re = new RegExp(regu);
  220. if (re.test(s)) {
  221. return true;
  222. } else {
  223. return false;
  224. }
  225. }
  226. //验证固定电话
  227. export function sldCheckTel(s) {
  228. let regu = /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/;
  229. let re = new RegExp(regu);
  230. if (re.test(s)) {
  231. return true;
  232. } else {
  233. return false;
  234. }
  235. }
  236. /**
  237. 检查输入的字符是否具有特殊字符
  238. 输入:str 字符串
  239. 返回:true 或 flase; true表示包含特殊字符
  240. 主要用于注册信息的时候验证
  241. */
  242. // export function sldCheckQuote(str) {
  243. // let items = new Array("~", "`", "!", "@", "#", "$", "%", "^", "&", "", "{", "}", "[", "]", "(", ")");
  244. // items.push(":", ";", "'", "|", "\", "<", ">", "?", "/", "<<", ">>", "||", "//");
  245. // items.push("admin", "administrators", "administrator", "管理员", "系统管理员");
  246. // items.push("select", "delete", "update", "insert", "create", "drop", "alter", "trancate");
  247. // str = str.toLowerCase();
  248. // for (var i = 0; i < items.length; i++) {
  249. // if (str.indexOf(items[i]) >= 0) {
  250. // return true;
  251. // }
  252. // }
  253. // return false;
  254. // }
  255. export const sld_token = localStorage.getItem('sld_token');
  256. export const goods_spec_list_page_size = 2;//商品管理—规格管理
  257. export const check_brand_list_page_size = 10;//待审核品牌
  258. export const goods_list_del_page_size = 10;//已删除商品列表
  259. export const list_com_page_size_10 = 10;
  260. export const list_com_page_size_5 = 5;
  261. export const list_com_page_size_7 = 7;
  262. export const list_com_page_size_15 = 15;
  263. export const list_com_page_size_20 = 20;
  264. export const list_com_page_size_16 = 16;
  265. export const list_com_page_more = 10000;
  266. export const mobile_reg = /(1[3-9]\d{9}$)/;//手机号的正则表达式
  267. export const formItemLayoutModal = {
  268. labelCol: {
  269. span: 6,
  270. },
  271. wrapperCol: {
  272. span: 14,
  273. },
  274. };
  275. export const formItemLayoutModalTwo = {
  276. labelCol: {
  277. span: 3,
  278. },
  279. wrapperCol: {
  280. span: 21,
  281. },
  282. };
  283. export function getTimeDistance(type) {
  284. const now = new Date();
  285. const oneDay = 1000 * 60 * 60 * 24;
  286. if (type === 'today') {
  287. now.setHours(0);
  288. now.setMinutes(0);
  289. now.setSeconds(0);
  290. return [moment(now), moment(now.getTime() + (oneDay - 1000))];
  291. }
  292. if (type === 'week') {
  293. let day = now.getDay();
  294. now.setHours(0);
  295. now.setMinutes(0);
  296. now.setSeconds(0);
  297. if (day === 0) {
  298. day = 6;
  299. } else {
  300. day -= 1;
  301. }
  302. const beginTime = now.getTime() - day * oneDay;
  303. return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))];
  304. }
  305. if (type === 'month') {
  306. const year = now.getFullYear();
  307. const month = now.getMonth();
  308. const nextDate = moment(now).add(1, 'months');
  309. const nextYear = nextDate.year();
  310. const nextMonth = nextDate.month();
  311. return [
  312. moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`),
  313. moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000),
  314. ];
  315. }
  316. const year = now.getFullYear();
  317. return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)];
  318. }
  319. export function getPlainNode(nodeList, parentPath = '') {
  320. const arr = [];
  321. nodeList.forEach(node => {
  322. const item = node;
  323. item.path = `${parentPath}/${item.path || ''}`.replace(/\/+/g, '/');
  324. item.exact = true;
  325. if (item.children && !item.component) {
  326. arr.push(...getPlainNode(item.children, item.path));
  327. } else {
  328. if (item.children && item.component) {
  329. item.exact = false;
  330. }
  331. arr.push(item);
  332. }
  333. });
  334. return arr;
  335. }
  336. export function digitUppercase(n) {
  337. return nzh.toMoney(n);
  338. }
  339. function getRelation(str1, str2) {
  340. if (str1 === str2) {
  341. console.warn('Two path are equal!'); // eslint-disable-line
  342. }
  343. const arr1 = str1.split('/');
  344. const arr2 = str2.split('/');
  345. if (arr2.every((item, index) => item === arr1[index])) {
  346. return 1;
  347. }
  348. if (arr1.every((item, index) => item === arr2[index])) {
  349. return 2;
  350. }
  351. return 3;
  352. }
  353. function getRenderArr(routes) {
  354. let renderArr = [];
  355. renderArr.push(routes[0]);
  356. for (let i = 1; i < routes.length; i += 1) {
  357. // 去重
  358. renderArr = renderArr.filter(item => getRelation(item, routes[i]) !== 1);
  359. // 是否包含
  360. const isAdd = renderArr.every(item => getRelation(item, routes[i]) === 3);
  361. if (isAdd) {
  362. renderArr.push(routes[i]);
  363. }
  364. }
  365. return renderArr;
  366. }
  367. /**
  368. * Get router routing configuration
  369. * { path:{name,...param}}=>Array<{name,path ...param}>
  370. * @param {string} path
  371. * @param {routerData} routerData
  372. */
  373. export function getRoutes(path, routerData) {
  374. let routes = Object.keys(routerData).filter(
  375. routePath => routePath.indexOf(path) === 0 && routePath !== path,
  376. );
  377. // Replace path to '' eg. path='user' /user/name => name
  378. routes = routes.map(item => item.replace(path, ''));
  379. // Get the route to be rendered to remove the deep rendering
  380. const renderArr = getRenderArr(routes);
  381. // Conversion and stitching parameters
  382. const renderRoutes = renderArr.map(item => {
  383. const exact = !routes.some(route => route !== item && getRelation(route, item) === 1);
  384. return {
  385. exact,
  386. ...routerData[`${path}${item}`],
  387. key: `${path}${item}`,
  388. path: `${path}${item}`,
  389. };
  390. });
  391. return renderRoutes;
  392. }
  393. export function getPageQuery() {
  394. return parse(window.location.href.split('?')[1]);
  395. }
  396. export function getQueryPath(path = '', query = {}) {
  397. const search = stringify(query);
  398. if (search.length) {
  399. return `${path}?${search}`;
  400. }
  401. return path;
  402. }
  403. /* eslint no-useless-escape:0 */
  404. const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
  405. export function isUrl(path) {
  406. return reg.test(path);
  407. }
  408. export function formatWan(val) {
  409. const v = val * 1;
  410. if (!v || Number.isNaN(v)) return '';
  411. let result = val;
  412. if (val > 10000) {
  413. result = Math.floor(val / 10000);
  414. result = (
  415. <span>
  416. {result}
  417. <span
  418. styles={{
  419. position: 'relative',
  420. top: -2,
  421. fontSize: 14,
  422. fontStyle: 'normal',
  423. lineHeight: 20,
  424. marginLeft: 2,
  425. }}
  426. >
  427. {this.sldComLanguage('万')}
  428. </span>
  429. </span>
  430. );
  431. }
  432. return result;
  433. }
  434. // 如果内容为空,返回-
  435. export function sldEmptyHandle1(str) {
  436. return (str === '' || str == null) ? '-' : str;
  437. }
  438. // 如果内容为空或者undefined,返回''
  439. export function sldEmptyHandle2(str) {
  440. return (str == undefined || str == null) ? '' : str;
  441. }
  442. // 给官方演示站点用,用于关闭真实开发环境不需要使用的特性
  443. export function isAntdPro() {
  444. return window.location.hostname === 'preview.pro.ant.design';
  445. }
  446. //返回左边一个竖线,右侧文字的结构
  447. export function sldLlineRtext(leftColor, Rtext) {
  448. return <div className={styles.title}>
  449. <span style={{ backgroundColor: leftColor }} className={styles.left_border}/>{Rtext}
  450. </div>;
  451. }
  452. //返回左边一个竖线,右侧文字的结构_添加商品(字体大小,颜色变化)
  453. export function sldLlineRtextAddGoods(leftColor, Rtext) {
  454. return <div className={styles.title_add_goods}>
  455. <span style={{ backgroundColor: leftColor }} className={styles.left_border}/><span>{Rtext}</span>
  456. </div>;
  457. }
  458. //返回左边一个竖线,右侧文字的结构_添加商品(字体大小,颜色变化) 增加上下左边的距离
  459. export function sldLlineRtextAddGoodsAddMargin(leftColor, Rtext, ml = 0, mt = 0, mb = 0, subTitle='') {
  460. return <div className={styles.title_add_goods} style={{ marginLeft: ml, marginTop: mt, marginBottom: mb }}>
  461. <span style={{ backgroundColor: leftColor }} className={styles.left_border}/>
  462. <span className={styles.title}>{Rtext}</span>
  463. {subTitle&&
  464. <span className={styles.sub_title}>{subTitle}</span>
  465. }
  466. </div>;
  467. }
  468. //通用的标题,有背景色和标题名称
  469. export function sldCommonTitleByBg(text) {
  470. return <div className={styles.common_title_bg}>
  471. <span className={styles.title}>{text}</span>
  472. </div>;
  473. }
  474. //通用的title(主要用于商品详情页)
  475. export function sldCommonTitle(context, cont_color = '#333333', ml = 5, mt = 20, mb = 20) {
  476. return <div
  477. style={{ marginLeft: ml, marginTop: mt, marginBottom: mb, fontSize: 14, color: cont_color, fontWeight: 'bold' }}>
  478. {context}
  479. </div>;
  480. }
  481. /*
  482. * 返回图标,下面文字
  483. * @params svg svg图标名称
  484. * @params text 底部文本
  485. * @params marginT 底部文本距离svg图标的距离
  486. * @params lindto 跳转连接
  487. * */
  488. export function sldTsvgBotText(svg, text, marginT, lindto = '', key, svgColor = '#5F96E3', width = 40, height = 40, font_color = '#555') {
  489. return <div key={key} className={styles.icon_text_width}>
  490. {lindto
  491. ?<Link to={lindto != '' ? lindto : '/'} className={styles.icon_text}>
  492. <ALibbSvg fill={svgColor} width={width} height={height} type={svg}/>
  493. <span style={{ marginTop: marginT, color: font_color }}>{text}</span>
  494. </Link>
  495. :<Fragment>
  496. <ALibbSvg fill={svgColor} width={width} height={height} type={svg}/>
  497. <span style={{ marginTop: marginT, color: font_color }}>{text}</span>
  498. </Fragment>
  499. }
  500. </div>;
  501. }
  502. /*
  503. * 返回图标
  504. * @params svg svg图标名称
  505. * @params color 图标颜色
  506. * @params width 图标宽度
  507. * @params height 图标高度
  508. * */
  509. export function sldTsvg(svg, color, width, height) {
  510. return <ALibbSvg fill={color} width={width} height={height} type={svg}/>;
  511. }
  512. /*
  513. * 成功提示
  514. * @params con 提示内容
  515. * @params time 提示时间
  516. * */
  517. export function sucTip(con, time = 2) {
  518. message.success(con, time);
  519. }
  520. /*
  521. * 失败提示
  522. * @params con 提示内容
  523. * @params time 提示时间
  524. * */
  525. export function failTip(con, time = 3) {
  526. // message.error(con, time);
  527. message.warn(con, time);
  528. }
  529. //根据路由获取页面名称
  530. function getPathName(pathname) {
  531. let path_array = pathname.split('/');
  532. let path_id = 'menu';
  533. for (let i = 0; i < path_array.length; i++) {
  534. if (path_array[i] != '') {
  535. path_id += '.' + path_array[i];
  536. }
  537. }
  538. return formatMessage({ id: path_id });
  539. }
  540. /*
  541. * @params props 为this.props
  542. *
  543. * */
  544. // Get the currently selected menu
  545. export function setTopRoute(props) {
  546. const {
  547. location: { pathname }, menuData,
  548. } = props;
  549. if (pathname == '/dashboard/commonuse/desc' || pathname == '/' || pathname.split('/').length == 2) {
  550. //如果是常用功能页面,不需要存路由,并将activeKey置空
  551. localStorage.setItem('activePaneKey', '');
  552. return false;
  553. }
  554. //如果该路由在缓存里,重置activekey,否则存缓存并重置activekey
  555. let storagePane = localStorage.getItem('storagePane');
  556. let name = `${sldComLanguage('默认页面')}`; //页面名称
  557. name = getPathName(pathname);
  558. let route_info = { title: name, key: pathname };
  559. if (pathname != '/' && pathname != '/dists/') {
  560. if (storagePane != undefined) {
  561. storagePane = JSON.parse(storagePane);
  562. //检测是否有一样的
  563. let flag = true;
  564. for (let i = 0; i < storagePane.length; i++) {
  565. if (storagePane[i].key == pathname) {
  566. flag = false;
  567. break;
  568. }
  569. }
  570. if (flag) {
  571. storagePane = storagePane.concat(route_info);
  572. localStorage.setItem('storagePane', JSON.stringify(storagePane));
  573. }
  574. } else {
  575. localStorage.setItem('storagePane', JSON.stringify([{ title: name, key: pathname }]));
  576. }
  577. }
  578. localStorage.setItem('activePaneKey', pathname);
  579. };
  580. /*
  581. * 删除单条数据确认提示框
  582. * @params position 展示位置
  583. * @params title 标题
  584. * @params callback 回调事件
  585. * @params okText 确认文本
  586. * @params cancleText 取消文本
  587. * @params showText 展示文本
  588. * */
  589. export function sldPopConfirm(position, title, callback, okText, cancleText, showText, paddingL = 0, paddingR = 0, color = '#555') {
  590. return <Popconfirm
  591. placement={position}
  592. title={title}
  593. onConfirm={callback}
  594. okText={okText}
  595. cancelText={cancleText}>
  596. <a style={{ paddingLeft: paddingL, paddingRight: paddingR, color: color }}
  597. onClick={(e) => e.preventDefault()}>{showText}</a>
  598. </Popconfirm>;
  599. }
  600. /*
  601. * 删除单条数据确认提示框,主要用于Dropdown 下面的menuitem样式
  602. * @params position 展示位置
  603. * @params title 标题
  604. * @params callback 回调事件
  605. * @params okText 确认文本
  606. * @params cancleText 取消文本
  607. * @params showText 展示文本
  608. * */
  609. export function sldPopConfirmMenu(position, title, callback, okText, cancleText, showText, paddingL = 0, paddingR = 0, color = '#555') {
  610. return <Popconfirm placement={position} title={title}
  611. onConfirm={callback} okText={okText} cancelText={cancleText}>
  612. <a style={{ color: color, fontSize: 12 }} onClick={(e) => e.preventDefault()}>{showText}</a>
  613. </Popconfirm>;
  614. }
  615. /*
  616. * 返回图标按钮——不带背景色
  617. * @params callback 按钮点击事件
  618. * @params svg svg图标
  619. * @params text 右侧文本
  620. * @params svgColor 图标颜色
  621. * @params wrapML 按钮左边距
  622. * @params wrapMR 按钮右边距
  623. * @params svgW 图标宽
  624. * @params svgH 图标高
  625. * @params textML 文字距离图标距离
  626. * */
  627. export function sldIconBtn(callback, text, wrapML, wrapMR, svgW = 15, svgH = 15, textML = 4, svg = 'xinzeng', svgColor = defaultSettings.primaryColor) {
  628. return <div style={{ marginLeft: wrapML, marginRight: wrapMR }} className={styles.sld_common_btn}
  629. onClick={callback}>
  630. <ALibbSvg fill={svgColor} width={svgW} height={svgH} type={svg}/>
  631. <span style={{ marginLeft: textML, fontSize: 13, color: '#333' }}>{text}</span>
  632. </div>;
  633. }
  634. /*
  635. * 返回图标按钮——不带背景色 和 sldIconBtn一样,但是不能点击,属于禁用按钮
  636. * @params callback 按钮点击事件
  637. * @params svg svg图标
  638. * @params text 右侧文本
  639. * @params svgColor 图标颜色
  640. * @params wrapML 按钮左边距
  641. * @params wrapMR 按钮右边距
  642. * @params svgW 图标宽
  643. * @params svgH 图标高
  644. * @params textML 文字距离图标距离
  645. * @params showTitle 禁止操作的提示
  646. * */
  647. export function sldIconBtnNo(callback, text, wrapML, wrapMR, svgW = 15, svgH = 15, textML = 4, svg = 'xinzeng', svgColor = defaultSettings.primaryColor, showTitle = `${sldComLanguage('禁止操作')}`) {
  648. return <div style={{ marginLeft: wrapML, marginRight: wrapMR }}
  649. className={`${styles.sld_common_btn} ${styles.sld_common_btn_not_allowed}`} title={showTitle}
  650. onClick={callback}>
  651. <ALibbSvg fill={svgColor} width={svgW} height={svgH} type={svg} opacity={.3}/>
  652. <span style={{ marginLeft: textML, fontSize: 13, color: '#cbcbcb' }}>{text}</span>
  653. </div>;
  654. }
  655. /*
  656. * 返回图标按钮——带背景色
  657. * @params callback 按钮点击事件
  658. * @params svg svg图标
  659. * @params text 右侧文本
  660. * @params svgColor 图标颜色
  661. * @params wrapML 按钮左边距
  662. * @params wrapMR 按钮右边距
  663. * @params svgW 图标宽
  664. * @params svgH 图标高
  665. * @params textML 文字距离图标距离
  666. * */
  667. export function sldIconBtnBg(callback, svg, text, svgColor, wrapML, wrapMR, svgW = 15, svgH = 15, textML) {
  668. return <div style={{ marginLeft: wrapML, marginRight: wrapMR, backgroundColor: defaultSettings.primaryColor }}
  669. className={styles.sld_common_btn} onClick={callback}>
  670. <ALibbSvg fill={svgColor} width={svgW} height={svgH} type={svg}/>
  671. <span style={{ marginLeft: textML, color: '#fff', fontSize: 13 }}>{text}</span>
  672. </div>;
  673. }
  674. /*
  675. * 返回搜索框
  676. * @params placeholder 搜索框默认文本
  677. * @params width 搜索框宽度
  678. * @params callback 按钮点击事件
  679. * @params btnText 按钮文本
  680. * @params value 搜索框默认值
  681. * */
  682. export function sldSearch(placeholder, width, callback, btnText, value = '') {
  683. return <Search
  684. placeholder={placeholder}
  685. enterButton={btnText}
  686. defaultValue={value}
  687. size="default"
  688. onSearch={value => callback(value)}
  689. style={{ width: width }}
  690. />;
  691. }
  692. /*
  693. * 返回搜索框——受控组件(重置搜索的时候自动清空搜索内容)
  694. * @params placeholder 搜索框默认文本
  695. * @params width 搜索框宽度
  696. * @params callback 按钮点击事件
  697. * @params btnText 按钮文本
  698. * @params value 搜索框默认值
  699. * @params callbackCon 搜索框值变化事件
  700. * */
  701. export function sldSearchVal(placeholder, width, callback, btnText, value, callbackCon) {
  702. return <Search
  703. placeholder={placeholder}
  704. enterButton={btnText}
  705. value={value}
  706. size="default"
  707. onSearch={value => callback(value)}
  708. onChange={callbackCon}
  709. style={{ width: width }}
  710. />;
  711. }
  712. /*
  713. * 返回搜索框——受控组件(重置搜索的时候自动清空搜索内容)增加删除按钮
  714. * * @params placeholder 搜索框默认文本
  715. * @params btnText 按钮文本
  716. * @params callback 按钮点击事件
  717. * */
  718. export function sldSearchValClear(placeholder, width, callback, btnText, value, callbackCon, clearcallback, rightV) {
  719. return <div style={{ position: 'relative' }}><Search
  720. placeholder={placeholder}
  721. enterButton={btnText}
  722. value={value}
  723. size="default"
  724. onSearch={value => callback(value)}
  725. onChange={callbackCon}
  726. style={{ width: width }}
  727. />{value &&
  728. <span onClick={clearcallback} style={{ position: 'absolute', top: 6, right: rightV, zIndex: 2, cursor: 'pointer' }}>{
  729. <ALibbSvg
  730. fill={'#c8c8c8'} width={14} height={14} type={'qingchu'}/>}</span>}</div>;
  731. }
  732. /*
  733. * 返回图标按钮_带背景色
  734. * @params callback 按钮点击事件
  735. * @params svg svg图标
  736. * @params text 右侧文本
  737. * @params svgColor 图标颜色
  738. * @params wrapML 按钮左边距
  739. * @params wrapMR 按钮右边距
  740. * @params svgW 图标宽
  741. * @params svgH 图标高
  742. * @params textML 文字距离图标距离
  743. * */
  744. export function sldIconBtnBorder(callback, svg, text, svgColor, wrapML, wrapMR, svgW, svgH, textML) {
  745. return <div
  746. style={{
  747. marginLeft: wrapML,
  748. marginRight: wrapMR,
  749. borderWidth: 1,
  750. borderStyle: 'solid',
  751. borderColor: '#E5E5E5',
  752. }}
  753. className={styles.sld_common_btn} onClick={callback}>
  754. <ALibbSvg fill={svgColor} width={svgW} height={svgH} type={svg}/>
  755. <span style={{ marginLeft: textML }}>{text}</span>
  756. </div>;
  757. }
  758. /*
  759. * 右上角消息通知
  760. * @params message 消息标题
  761. * @params desc 消息描述
  762. * @params icon 图标
  763. * @params iconcolor 图标颜色
  764. * */
  765. export function sldNoticeRightTop(message, desc, icon, iconcolor) {
  766. return notification.open({
  767. message: message,
  768. description: desc,
  769. icon: <Icon type={icon} style={{ color: iconcolor }}/>,
  770. duration: 2,
  771. });
  772. }
  773. /*
  774. * 表格内文字过多的展示处理
  775. * @params message 消息标题
  776. * @params desc 消息描述
  777. * @params icon 图标
  778. * @params iconcolor 图标颜色
  779. * */
  780. export function sldRowMoreShow(text, length) {
  781. let res = '';
  782. if (text.length == 0) {
  783. res = '';
  784. } else if (text.length <= length) {
  785. res = text;
  786. } else {
  787. res = <Tooltip placement="topLeft" title={text}>
  788. {text.substr(0, length) + '...'}
  789. </Tooltip>;
  790. }
  791. return res;
  792. }
  793. /*
  794. * 文字左右两个部分展示
  795. * @params left_text 左部分文字
  796. * @params right_text 右部分文字
  797. * */
  798. export function sldRowTextShow(left_text, right_text) {
  799. return <div className={styles.weight_r_span_wrap}><span
  800. className={styles.weight_w_left_span}>{left_text}</span><span
  801. className={styles.weight_w_right_span}>{right_text}</span></div>;
  802. }
  803. /*
  804. * 文字左右两个部分展示,居于两端
  805. * @params left_text 左部分文字
  806. * @params right_text 右部分文字
  807. * */
  808. export function sldRowTextShowBetweent(left_text, right_text) {
  809. return <div className={styles.weight_r_span_wrap_betweent}><span
  810. style={{ justifyContent: 'flex-start', paddingLeft: 11 }}
  811. className={styles.weight_w_left_span}>{left_text}</span><span style={{ justifyContent: 'flex-end' }}
  812. className={styles.weight_w_right_span}>{right_text}</span>
  813. </div>;
  814. }
  815. /*
  816. * 删除某个tab的数据
  817. * @params del_tab 要删除的tab
  818. * */
  819. export function sldDelTab(del_tab) {
  820. let pane = JSON.parse(localStorage.getItem('storagePane'));
  821. pane = pane.filter(pane => pane.key !== del_tab);
  822. localStorage.setItem('storagePane', JSON.stringify(pane));
  823. }
  824. /**
  825. * 帮助提示_单条提示
  826. * @params string con 展示的内容
  827. */
  828. export function showHelpTip(con) {
  829. return <div className={styles.help_wrap}>
  830. {con}
  831. </div>;
  832. }
  833. /**
  834. * 帮助提示_多条提示
  835. * @params string title 提示标题
  836. * @params string tip_array 提示详情
  837. * @params number marginT 提示模块距离上方距离
  838. * @params boolean sld_show_tip 是否显示提示内容
  839. */
  840. export function showMoreHelpTip(title, tip_array, marginT = 0, sld_show_tip = true) {
  841. if (!commonSetting.operateTipSwitch) {
  842. sld_show_tip = false;
  843. }
  844. return sld_show_tip
  845. ? <div className={styles.diy_tip_div} style={{ marginTop: marginT }}>
  846. <span>{title}</span>
  847. <ul>
  848. {tip_array.map((item, index) => {
  849. return <li key={index}>• {item}</li>;
  850. })}
  851. </ul>
  852. </div>
  853. : null
  854. ;
  855. }
  856. /**
  857. * 帮助提示_多条提示_装修modal弹框处,没有背景
  858. * @params string con 展示的内容
  859. */
  860. export function showMoreModalHelpTip(tip_array) {
  861. return <div className={styles.diy_modal_tip_div}>
  862. <ul>
  863. {tip_array.map((item, index) => {
  864. return <li key={index}>• {item}</li>;
  865. })}
  866. </ul>
  867. </div>;
  868. }
  869. //通用的年月日
  870. export const dateFormat = 'YYYY-MM-DD';
  871. export const dateTimeFormat = 'YYYY-MM-DD HH:mm:ss';
  872. /*
  873. * 删除单条数据确认提示框_除了提示框 别的东西都是自定义
  874. * @params position 展示位置
  875. * @params title 标题
  876. * @params callback 回调事件
  877. * @params okText 确认文本
  878. * @params cancleText 取消文本
  879. * @params content 展示内容
  880. * */
  881. export function sldPopConfirmDiy(position, title, callback, okText, cancleText, content) {
  882. return <Popconfirm placement={position} title={title}
  883. onConfirm={callback} okText={okText} cancelText={cancleText}>
  884. {content}
  885. </Popconfirm>;
  886. }
  887. /**
  888. * 验证输入的是否是英文字母
  889. */
  890. export function validatorLetter(rule, value, callback) {
  891. let reg = /^[A-Za-z]+$/;
  892. if (!reg.test(value)) {
  893. callback(`${sldComLanguage('请输入正确的首字母')}`);
  894. }
  895. callback();
  896. }
  897. /**
  898. * 验证大小在0~255范围内
  899. */
  900. export function validatorNumbe(rule, value, callback) {
  901. if (!(value >= 0 && value <= 255)) {
  902. callback(`${sldComLanguage('请输入0~255的数字')}`);
  903. }
  904. callback();
  905. }
  906. /**
  907. * 验证会员名,由中、英文、数字、"-"及"_",且不能全为数字
  908. */
  909. export function validatorMem(rule, value, callback) {
  910. let reg = new RegExp('^([\u4E00-\uFA29]|[\uE7C7-\uE7F3]|[a-zA-Z0-9_-]){1,20}$');
  911. let reg_num = new RegExp('^[0-9]*$');
  912. if (!value || value.replace(/(^\s*)|(\s*$)/g, '') == '') {
  913. callback();
  914. }
  915. if (value.length < 6 || value.length > 20) {
  916. callback(`${sldComLanguage('请输入6-20位的会员名')}`);
  917. } else {
  918. if (reg.test(value)) {
  919. if (reg_num.test(value)) {
  920. callback(`${sldComLanguage('会员名不能全为数字')}`);
  921. } else {
  922. callback();
  923. }
  924. } else {
  925. callback(`${sldComLanguage('会员名须由中、英文、数字、"-"及"_"组成')}`);
  926. }
  927. }
  928. }
  929. /**
  930. * 验证会员的密码,6~20位,由字母、数字或符号组成的验证
  931. */
  932. export function validatorMemPwd(rule, value, callback) {
  933. if (value.length < 6 || value.length > 20) {
  934. callback(`${sldComLanguage('请输入6~20位的密码')}`);
  935. } else if (/[\u4E00-\u9FA5]/g.test(value)) {
  936. callback(`${sldComLanguage('密码不可以有中文')}`);
  937. } else if (!(/^\S*$/.test(value))) {
  938. callback(`${sldComLanguage('密码中不可以有空格')}`);
  939. } else {
  940. callback();
  941. }
  942. }
  943. /**
  944. * 验证数据都是正整数
  945. */
  946. export function validatorIntegerPositive(rule, value, callback) {
  947. let reg = /^[1-9]\d*$/;
  948. if (value && !reg.test(value)) {
  949. return false;
  950. }
  951. return true;
  952. }
  953. /**
  954. * 验证数据都是正整数,react from表单验证
  955. */
  956. export function validatorIntegerPositiveForm(rule, value, callback) {
  957. let reg = /^[1-9]\d*$/;
  958. if (value && !reg.test(value)) {
  959. callback(`${sldComLanguage('请输入正整数')}`);
  960. }
  961. callback();
  962. }
  963. /**
  964. * 验证数据都是2~999的整数
  965. */
  966. export function validatorConversionRatio(rule, value, callback) {
  967. let reg = /^[1-9]\d*$/;
  968. value = value * 1;
  969. if (value) {
  970. if (!reg.test(value)) {
  971. callback(`${sldComLanguage('请输入2~999的整数')}`);
  972. } else if (value < 2 || value > 999) {
  973. callback(`${sldComLanguage('请输入2~999的整数')}`);
  974. }
  975. }
  976. callback();
  977. }
  978. /**
  979. * 验证数据都是1~99999的整数
  980. */
  981. export function validatorGoodsValidity(rule, value, callback) {
  982. let reg = /^[1-9]\d*$/;
  983. value = value * 1;
  984. if (value) {
  985. if (!reg.test(value)) {
  986. callback(`${sldComLanguage('请输入1~99999的整数')}`);
  987. } else if (value < 1 || value > 99999) {
  988. callback(`${sldComLanguage('请输入1~99999的整数')}`);
  989. }
  990. } else {
  991. callback(`${sldComLanguage('请输入1~99999的整数')}`);
  992. }
  993. callback();
  994. }
  995. /**
  996. * 验证银行卡号限制21位
  997. */
  998. export function validatorBankCode(rule, value, callback) {
  999. let res = validatorIntegerPositive(rule, value, callback);
  1000. if (value && (value + '').length > 22 || !res) {
  1001. callback(`${sldComLanguage('请输入正确的数据')}`);
  1002. }
  1003. callback();
  1004. }
  1005. /**
  1006. * 获取表格序号
  1007. */
  1008. export function getTableNum(params, pageSize, index) {
  1009. let cur_page = params.current != undefined ? params.current : 1;
  1010. return (cur_page - 1) * pageSize + index + 1;
  1011. }
  1012. /**
  1013. * 返回上下拖动的拖动条
  1014. */
  1015. export function getSldResizeBar() {
  1016. return <div style={{ position: 'relative' }}>
  1017. <div style={{ width: '100%', height: 4, backgroundColor: '#c5cfdc', position: 'absolute', zIndex: 1 }}>
  1018. </div>
  1019. </div>;
  1020. }
  1021. /**
  1022. * 获取商品列表商品图片的展示
  1023. */
  1024. export function getSldListGoodsImg(img_url) {
  1025. return img_url ? <div className={`${styles.flex_com_row_center}`}>
  1026. <Popover placement="rightTop"
  1027. content={<div className={`${styles.flex_com_row_center} ${styles.goods_img_wrap_160}`}>
  1028. <img src={img_url}/>
  1029. </div>}>
  1030. <div className={`${styles.flex_com_row_center} ${styles.goods_img_wrap_30}`}>
  1031. <img src={img_url}/>
  1032. </div>
  1033. </Popover>
  1034. </div> : null;
  1035. }
  1036. /**
  1037. * 多媒体管理部分的图片预览
  1038. */
  1039. export function getSldListGoodsImg80ByMedia(img_url) {
  1040. return img_url ? <div className={`${styles.flex_com_row_center}`}>
  1041. <Popover placement="rightTop"
  1042. content={<div className={`${styles.flex_com_row_center} ${styles.goods_img_wrap_200}`}>
  1043. <img src={img_url}/>
  1044. </div>}>
  1045. <div className={`${styles.flex_com_row_center} ${styles.goods_img_wrap_80}`}>
  1046. <span>{/*图片*/}<img src={img_url}/>{/*<a className={'action'}>预览</a>*/}</span>
  1047. </div>
  1048. </Popover>
  1049. </div> : null;
  1050. }
  1051. /**
  1052. * 获取商品列表商品图片的展示
  1053. */
  1054. export function getSldListGoodsImg80(img_url) {
  1055. return img_url ? <div className={`${styles.flex_com_row_center}`}>
  1056. <Popover placement="rightTop"
  1057. content={<div className={`${styles.flex_com_row_center} ${styles.goods_img_wrap_200}`}>
  1058. <img src={img_url}/>
  1059. </div>}>
  1060. <div className={`${styles.flex_com_row_center} ${styles.goods_img_wrap_80}`}>
  1061. <img src={img_url}/>
  1062. </div>
  1063. </Popover>
  1064. </div> : null;
  1065. }
  1066. /**
  1067. * 审核通过拒绝处理是否必填数据
  1068. * @param array data 要处理的数据
  1069. * @param e radio选择的结果
  1070. * @param array filed 字段名,要对哪个数据进行处理
  1071. */
  1072. export function sldHandleCheckData(data, e, filed) {
  1073. for (let i in data) {
  1074. if (data[i].name == filed) {
  1075. if (e.target.value) {
  1076. //通过 审核意见非必填
  1077. delete data[i].rules;
  1078. } else {
  1079. //拒绝 审核意见必填
  1080. data[i].rules = [{
  1081. required: true,
  1082. whitespace: true,
  1083. message: `${sldComLanguage('请输入审核意见')}`,
  1084. }];
  1085. }
  1086. break;
  1087. }
  1088. }
  1089. return data;
  1090. }
  1091. /**
  1092. * 验证输入的是否是特殊字符
  1093. * @params String str 验证的字符串
  1094. */
  1095. export function validatorSpecialString(rule, value, callback) {
  1096. const regs = /[`~!@¥#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
  1097. if (value && regs.test(value)) {
  1098. callback(`${sldComLanguage('检测到有特殊字符,请重新输入')}`);
  1099. }
  1100. callback();
  1101. }
  1102. /**
  1103. * input_after 后缀样式
  1104. */
  1105. export function sldInputAfterAddons() {
  1106. return <span className={styles.input_after_wrap}
  1107. style={{ marginLeft: 5, marginRight: 5 }}>{sldTsvg('sousuo1', '#666', 16, 16)}</span>;
  1108. }
  1109. /**
  1110. * 多语言-统一获取语言
  1111. */
  1112. export function sldComLanguage(name) {
  1113. const selectedLang = getLocale();
  1114. return name != undefined && name ? (selectedLang == 'zh-CN' ? name : formatMessage({ id: name })) : '';
  1115. }
  1116. /**
  1117. * 上传图片限制,限制的大小是服务器的配置
  1118. */
  1119. export function sldBeforeUpload(file, fileList, limit = uploadLimit) {
  1120. if (file.size != undefined && file.size > 1024 * 1024 * limit) {
  1121. failTip(`${sldComLanguage('上传文件过大,请上传小于')}` + { limit } + `${sldComLanguage('M的图片')}`);
  1122. return false;
  1123. }
  1124. }
  1125. /**
  1126. * 表格里的操作按钮,后续增加了判断,主要解决<a> cannot appear as a descendant of <a>这个警告
  1127. */
  1128. export function sldtbaleOpeBtn(text, svg, callback, svgW = 14, svgH = 14) {
  1129. return callback == null
  1130. ? <span title={text} style={{ marginRight: 3 }}>
  1131. <ALibbSvg fill={defaultSettings.primaryColor} width={svgW} height={svgH} type={svg}/>
  1132. </span>
  1133. : <a onClick={(e) => {e.preventDefault(); callback(e) }} title={text} style={{ marginRight: 3 }}>
  1134. <ALibbSvg fill={defaultSettings.primaryColor} width={svgW} height={svgH} type={svg}/>
  1135. </a>;
  1136. }
  1137. /**
  1138. * 表格里的操作按钮,Link跳转用
  1139. */
  1140. export function sldtbaleOpeLink(text, svg, svgW = 14, svgH = 14) {
  1141. return <span title={text} style={{ marginRight: 3 }}>
  1142. <ALibbSvg fill={defaultSettings.primaryColor} width={svgW} height={svgH} type={svg}/>
  1143. </span>;
  1144. }
  1145. /**
  1146. * 获取列表图片的展示+预览效果
  1147. * @params String img_url 图片地址
  1148. * @params String showW 图片预览的宽度
  1149. * @params String showH 图片预览的高度
  1150. * @params String viewW 图片展示的宽度
  1151. * @params String viewH 图片展示的高度
  1152. */
  1153. export function getSldComImg(img_url, showW, showH, viewW, viewH) {
  1154. return img_url ? <div className={`${styles.flex_com_row_center}`}>
  1155. <Popover placement="rightTop"
  1156. content={<div className={`${styles.flex_com_row_center} ${styles.com_img_wrap}`}
  1157. style={{ width: showW, height: showH }}>
  1158. <img src={img_url}/>
  1159. </div>}>
  1160. <div className={`${styles.flex_com_row_center} ${styles.com_img_wrap}`}
  1161. style={{ width: viewW, height: viewH, margin: '0 5px' }}>
  1162. <img src={img_url}/>
  1163. </div>
  1164. </Popover>
  1165. </div> : null;
  1166. }
  1167. /*
  1168. * 获取缓存中图片信息
  1169. * @params name 缓存的键
  1170. * */
  1171. export function getSldImgSet(name) {
  1172. return localStorage.getItem(name) != undefined && localStorage.getItem(name) ? JSON.parse(localStorage.getItem(name)) : '';
  1173. }
  1174. /*
  1175. * 圆形背景里面展示图标,用户装修模块的操作
  1176. * @params callback 点击事件
  1177. * @params svgW 图标宽度
  1178. * @params svgH 图标高度
  1179. * @params svg 图标
  1180. * @params svgColor 图标颜色
  1181. * */
  1182. export function getOSvgMDiy(callback, svg, svgColor, svgW = 15, svgH = 15) {
  1183. return <div onClick={(e) => {e.preventDefault(); callback(e) }}
  1184. className={`${styles.mdiy_operate_a} ${styles.flex_row_center_center}`} style={{ height: 30 }}>
  1185. <ALibbSvg fill={svgColor} width={svgW} height={svgH} type={svg} extra={{ marginLeft: 15 }}/>
  1186. </div>;
  1187. }
  1188. /*
  1189. *返回统计图标Y轴的标题样式
  1190. * */
  1191. export function getSldStatYTitle() {
  1192. return {
  1193. textStyle: {
  1194. fontSize: '12',
  1195. textAlign: 'center',
  1196. fill: '#666',
  1197. fontWeight: 'bold',
  1198. }, // 坐标轴文本属性配置
  1199. };
  1200. }
  1201. /*
  1202. *封装的请求
  1203. * method:请求方式 get post
  1204. * url 访问地址
  1205. * params 参数
  1206. * data_type json json格式 默认是表单提交
  1207. * */
  1208. export function sldComRequest(method, url, params, data_type = '') {
  1209. const state = window.g_app._store.getState();
  1210. const { webSite = '' } = state.routing.location.query;
  1211. const currentSite = webSite || state.global.currentSite || localStorage.getItem('currentSite');
  1212. const currentPath = state.routing.location.pathname;
  1213. if (!currentPath.includes('/user/login')) {
  1214. params = Object.assign({}, { webSite: currentSite }, params ?? {})
  1215. }
  1216. if (params && params.isAll) {
  1217. delete params.isAll;
  1218. delete params.webSite;
  1219. }
  1220. if (method == 'get') {
  1221. let tmp_url = apiUrl + `${url}`;
  1222. if (params != undefined && !isEmpty(params)) {
  1223. tmp_url += `?${stringify(params)}`;
  1224. }
  1225. return request(tmp_url);
  1226. } else if (method == 'post') {
  1227. if (data_type == 'json') {
  1228. return request(apiUrl + `${url}`, {
  1229. method: 'POST',
  1230. body: params,
  1231. }, 'json');
  1232. } else {
  1233. return request(apiUrl + `${url}`, {
  1234. method: 'POST',
  1235. body: `${stringify(params)}`,
  1236. });
  1237. }
  1238. }
  1239. }
  1240. /**
  1241. * 获取页面横线
  1242. */
  1243. export function getSldHorLine(num) {
  1244. return <div style={{ height: num }} className={styles.com_line}></div>;
  1245. }
  1246. /**
  1247. * 获取页面横线
  1248. * @param {number} num 横线高度
  1249. * @param {string} bgColor 横线的颜色
  1250. */
  1251. export function getSldHorLineBgColor(num, bgColor) {
  1252. return <div style={{ height: num, background: bgColor }} className={styles.com_line}></div>;
  1253. }
  1254. export async function sldCommonService(params, method, url, data_type = '') {
  1255. let cur_time = new Date().getTime();
  1256. let start_time = localStorage.getItem('time');
  1257. let sld_refresh_token = localStorage.getItem('sld_refresh_token');
  1258. //不需要token的接口
  1259. let speial_request = [
  1260. 'v3/adminLogin/oauth/token',//登录
  1261. 'v3/adminLogin/oauth/logout',//退出登录
  1262. 'v3/captcha/common/getCaptcha',//获取验证码
  1263. 'v3/system/admin/setting/getPcMainImage',//获取登录页图片
  1264. ];
  1265. let updateFlag = start_time && (cur_time - start_time > (58 * 60 * 1000)) && speial_request.indexOf(url) == -1 && sld_refresh_token != undefined && sld_refresh_token != null;
  1266. // console.info('调试是否更新token的条件:',updateFlag);
  1267. if (updateFlag) {
  1268. // console.info('通过refresh_token刷新token');
  1269. //用户token过期之后重新根据refresh_token获取token(58分钟,token的有效期是60分钟)
  1270. let res = await refreshToken();
  1271. if (res.state == 200) {
  1272. localStorage.setItem('sld_token', res.data.access_token);
  1273. localStorage.setItem('sld_refresh_token', res.data.refresh_token);
  1274. //更新sld_token的时间
  1275. setLocalStorageTime();
  1276. return sldComRequest(method, url, params, data_type);
  1277. } else {
  1278. loginOut();
  1279. }
  1280. } else {
  1281. return sldComRequest(method, url, params, data_type);
  1282. }
  1283. }
  1284. export const safeJsonParse = (val, defaultValue) => {
  1285. try {
  1286. return JSON.parse(val);
  1287. } catch {
  1288. return defaultValue ?? {};
  1289. }
  1290. };
  1291. async function refreshToken() {
  1292. let param = new FormData();
  1293. param.append('grant_type', 'refresh_token');
  1294. param.append('refresh_token', localStorage.getItem('sld_refresh_token'));
  1295. let result = await fetch(apiUrl + 'v3/adminLogin/oauth/token', {
  1296. credentials: 'include',
  1297. headers: {
  1298. Authorization: 'Basic VVcxS2FsRlhVblJoVnpROTpVMjFHTWxsVlFrUmlNMEkxVlcxc2JtRklVa0ZWTW5oMldrYzVkUT09',
  1299. },
  1300. method: 'POST',
  1301. body: param,
  1302. }).then(response => response.json());
  1303. return result;
  1304. }
  1305. /**
  1306. * 文字过多 表个列只展示一部分,鼠标悬浮展示全部
  1307. * @param {string} str 展示的数据
  1308. * @param {number} strDefaultLength 默认展示的字数
  1309. * @param {string} popWidth 弹窗的宽度
  1310. * @param {string} popHeight 弹窗的高度
  1311. */
  1312. export function getSldComShowMoreTtex(str, strDefaultLength, popWidth, popHeight = '') {
  1313. return str && str.length > strDefaultLength ? <Popover placement="rightTop"
  1314. content={<div style={{
  1315. width: popWidth,
  1316. height: popHeight ? popHeight : 'auto',
  1317. wordBreak: 'break-all',
  1318. }}>
  1319. {str}
  1320. </div>}>
  1321. <div>
  1322. {str.length > strDefaultLength ? str.substr(0, strDefaultLength - 1) + '...' : str}
  1323. </div>
  1324. </Popover> : str;
  1325. }
  1326. /**
  1327. * 对象数组实现深拷贝
  1328. * @param {array} origion_data 源对象数组
  1329. */
  1330. export function getSldCopyData(origion_data) {
  1331. let new_data = [];
  1332. if (origion_data.length > 0) {
  1333. for (let i in origion_data) {
  1334. if (typeof origion_data[i] == 'object') {
  1335. new_data.push({ ...origion_data[i] });
  1336. } else {
  1337. new_data.push(origion_data[i]);
  1338. }
  1339. }
  1340. }
  1341. return new_data;
  1342. }
  1343. /**
  1344. * 对象数组实现深拷贝
  1345. * @param {array} origion_data 源对象数组
  1346. */
  1347. export function getSldCopyDataPlus(origion_data) {
  1348. let new_data = [];
  1349. if (origion_data.length > 0) {
  1350. for (let i in origion_data) {
  1351. const single = origion_data[i];
  1352. if (!single.hide) {
  1353. if (typeof origion_data[i] == 'object') {
  1354. new_data.push({ ...origion_data[i] });
  1355. } else {
  1356. new_data.push(origion_data[i]);
  1357. }
  1358. }
  1359. }
  1360. }
  1361. return new_data;
  1362. }
  1363. /**
  1364. * 页面要适应高度,不同屏幕获取相应的高度,高度以1080为准,传入的值直接是1080设计图的尺寸就可以
  1365. */
  1366. export function sldFullHeight(height) {
  1367. return Math.round(document.body.clientHeight * height / 1920);
  1368. }
  1369. /*
  1370. * 笛卡尔积返回商品的SKU
  1371. * 参数的格式:二维数组,eg:[[1, 2, 3], ['a', 'b', 'c']]
  1372. * */
  1373. export function calcDescartes(array) {
  1374. if (array.length < 2) return array[0] || [];
  1375. return [].reduce.call(array, function(col, set) {
  1376. var res = [];
  1377. col.forEach(function(c) {
  1378. set.forEach(function(s) {
  1379. var t = [].concat(Array.isArray(c) ? c : [c]);
  1380. t.push(s);
  1381. res.push(t);
  1382. });
  1383. });
  1384. return res;
  1385. });
  1386. }
  1387. /**
  1388. * 表格里的操作按钮,后续增加了判断,主要解决<a> cannot appear as a descendant of <a>这个警告
  1389. * 按钮用文字表示
  1390. */
  1391. export function sldtbaleOpeBtnText(text, callback, svgW = 14, svgH = 14) {
  1392. return callback == null
  1393. ? <span className={styles.tableOperateText} style={{ marginRight: 3 }}>
  1394. {text}
  1395. </span>
  1396. : <a className={styles.tableOperateText} onClick={(e) => {e.preventDefault(); callback(e) }} title={text}
  1397. style={{ marginRight: 3 }}>
  1398. {text}
  1399. </a>;
  1400. }
  1401. /*
  1402. * 返回一个数字的整数和小数
  1403. * number 需要处理的数据
  1404. * type: 要获取的数据 int 整数 decimal 小数
  1405. */
  1406. export function getPartNumber(number, type) {
  1407. let target = '';
  1408. if (number == undefined) {
  1409. return false;
  1410. }
  1411. number = number.toString();
  1412. if (type == 'int') {
  1413. target = number.split('.')[0];
  1414. } else if (type == 'decimal') {
  1415. target = number.split('.')[1] != undefined ? ('.' + number.split('.')[1]) : '.00';
  1416. if (target.length < 3) {
  1417. target += '0';
  1418. }
  1419. }
  1420. return target;
  1421. }
  1422. /**
  1423. * 验证邮箱
  1424. */
  1425. export function validatorVendorEmail(rule, value, callback) {
  1426. if (!value || value.replace(/(^\s*)|(\s*$)/g, '') == '') {
  1427. callback();
  1428. }
  1429. if (value) {
  1430. if (sldCheckEmail(value)) {
  1431. callback();
  1432. } else {
  1433. callback(`${sldComLanguage('请输入正确的邮箱')}`);
  1434. }
  1435. } else {
  1436. callback();
  1437. }
  1438. }
  1439. /**
  1440. * 验证手机号
  1441. */
  1442. export function validatorVendorMobile(rule, value, callback) {
  1443. if (!value || value.replace(/(^\s*)|(\s*$)/g, '') == '') {
  1444. callback();
  1445. }
  1446. if (value) {
  1447. if (sldCheckMobile(value)) {
  1448. callback();
  1449. } else {
  1450. callback(`${sldComLanguage('请输入正确的手机号')}`);
  1451. }
  1452. } else {
  1453. callback();
  1454. }
  1455. }
  1456. /**
  1457. * 比较2个纯数字数组是否相等
  1458. * a,b 为要比较的数字数组
  1459. * 相等返回true,否则返回false
  1460. */
  1461. export function isEqualArray(a, b) {
  1462. if (a.length > 0 && b.length > 0) {
  1463. return a.sort().toString() == b.sort().toString();
  1464. }
  1465. if (a.length == 0 && b.length == 0) {
  1466. return true;
  1467. }
  1468. return false;
  1469. }
  1470. /*
  1471. * 格式化数字,超过1万的处理成单位为W的数据,未超过的不处理
  1472. * */
  1473. export function formatNumW(num) {
  1474. let result = 0;
  1475. num = num * 1;
  1476. if (num < 10000) {
  1477. result = num;
  1478. } else {
  1479. result = (num / 10000).toFixed(2) + 'w';
  1480. }
  1481. return result;
  1482. }
  1483. /*
  1484. 判断是否是IE 11及以下或者其他(其他里包括IE edge)
  1485. */
  1486. export function isIE() {
  1487. if (!!window.ActiveXObject || 'ActiveXObject' in window) {
  1488. return true;
  1489. } else {
  1490. return false;
  1491. }
  1492. }
  1493. /*
  1494. 格式化月或者日,小于10的时候前面用0补齐
  1495. */
  1496. export function formatMonthOrDay(val) {
  1497. let resutl = val * 1;
  1498. if (resutl < 10) {
  1499. resutl = '0' + val;
  1500. }
  1501. return resutl;
  1502. }
  1503. export function noDataPlaceholder(width = '120px', tips = '暂无数据') {
  1504. return <div className={`${styles.flex_column_center_center}`} style={{ width: '100%', height: '100%' }}>
  1505. <img style={{ width }} src={require('../assets/table_nodata_icon.png')} alt=''/>
  1506. <span style={{ fontSize: '12px', color: '#C3C3C3', marginTop: '10px' }}>{tips}</span>
  1507. </div>;
  1508. }
  1509. /*
  1510. * 获取昨天的日期 返回的结果如:2021-07-01
  1511. * */
  1512. export function sldGetYesterdayDate() {
  1513. let today = new Date();
  1514. today.setTime(today.getTime() - 24 * 60 * 60 * 1000);
  1515. let target = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
  1516. return target;
  1517. }
  1518. /*
  1519. * 数字格式化,增加单位万,减少数据长度,返回数据如:1.5万或者8,999
  1520. * @param {Number} num 要格式化的数据
  1521. * */
  1522. export function formatNum(num, toFixedNum = 0, color = '#333') {
  1523. let target = num * 1;
  1524. let unit = '';
  1525. if (target) {
  1526. if (target < 10000) {
  1527. target = target.toFixed(toFixedNum);
  1528. } else {
  1529. target = (target / 10000).toFixed(toFixedNum) * 1;
  1530. unit = '万';
  1531. }
  1532. let regExpInfo = /(\d{1,3})(?=(\d{3})+(?:$|\.))/g;
  1533. target = target.toString().replace(regExpInfo, '$1,');
  1534. } else {
  1535. target = num;
  1536. }
  1537. return <Fragment><span className={styles.statNumVal}>{target}</span><span className={styles.statNumUnit}
  1538. style={{ color: color }}>{unit}</span></Fragment>;
  1539. }
  1540. /*
  1541. * 数字格式化,增加单位万,减少数据长度,返回数据如:1.5万或者8,999
  1542. * @param {Number} num 要格式化的数据
  1543. * */
  1544. export function formatNumPieCircle(num, toFixedNum = 0) {
  1545. let target = num * 1;
  1546. let unit = '';
  1547. if (target) {
  1548. if (target < 10000) {
  1549. target = target.toFixed(toFixedNum);
  1550. } else {
  1551. target = (target / 10000).toFixed(1) * 1;
  1552. unit = '万';
  1553. }
  1554. let regExpInfo = /(\d{1,3})(?=(\d{3})+(?:$|\.))/g;
  1555. target = target.toString().replace(regExpInfo, '$1,');
  1556. target = target + unit;
  1557. } else {
  1558. target = num;
  1559. }
  1560. return target;
  1561. }
  1562. /*
  1563. * 去除字符串左右两端的空格
  1564. * @param {String} str 去除空格的字符串
  1565. * */
  1566. export function trimString(str) {
  1567. return str.replace(/(^\s*)|(\s*$)/g, '');
  1568. }
  1569. /*
  1570. * 统计事件
  1571. * @param {Object} data 统计数据
  1572. * */
  1573. export function sldStatEvent(data) {
  1574. //将data和公共属性合并得到最终要发送的数据
  1575. let sldStatCommonProperty = {
  1576. pageUrl: window.location.href,
  1577. referrerPageUrl: document.referrer,
  1578. equipmentType: 3, //设备类型,1-pc,2-移动设备,3-其他
  1579. };
  1580. let targetParams = {
  1581. ...sldStatCommonProperty,
  1582. ...data,
  1583. };
  1584. //日志开启的话需要打印数据
  1585. if (sldStatShowDebug) {
  1586. console.info('统计传输数据: ', targetParams);
  1587. }
  1588. let param = new FormData();
  1589. param.append('u', base64Encode(JSON.stringify(targetParams)));
  1590. //发送请求
  1591. fetch(apiUrl + 'v3/statistics/front/member/behavior/save', {
  1592. credentials: 'include',
  1593. headers: {
  1594. Authorization: 'Basic VVcxS2FsRlhVblJoVnpROTpVMjFHTWxsVlFrUmlNMEkxVlcxc2JtRklVa0ZWTW5oMldrYzVkUT09',
  1595. },
  1596. method: 'POST',
  1597. body: param,
  1598. });
  1599. }
  1600. /**
  1601. * base64加密
  1602. * @params data String 要加密的字符串
  1603. * @zjf-2021-06-28
  1604. */
  1605. export function base64Encode(data) {
  1606. let b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  1607. let o1,
  1608. o2,
  1609. o3,
  1610. h1,
  1611. h2,
  1612. h3,
  1613. h4,
  1614. bits,
  1615. i = 0,
  1616. ac = 0,
  1617. enc = '',
  1618. tmp_arr = [];
  1619. if (!data) {
  1620. return data;
  1621. }
  1622. data = utf8Encode(data);
  1623. do {
  1624. o1 = data.charCodeAt(i++);
  1625. o2 = data.charCodeAt(i++);
  1626. o3 = data.charCodeAt(i++);
  1627. bits = o1 << 16 | o2 << 8 | o3;
  1628. h1 = bits >> 18 & 0x3f;
  1629. h2 = bits >> 12 & 0x3f;
  1630. h3 = bits >> 6 & 0x3f;
  1631. h4 = bits & 0x3f;
  1632. tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  1633. } while (i < data.length);
  1634. enc = tmp_arr.join('');
  1635. switch (data.length % 3) {
  1636. case 1:
  1637. enc = enc.slice(0, -2) + '==';
  1638. break;
  1639. case 2:
  1640. enc = enc.slice(0, -1) + '=';
  1641. break;
  1642. }
  1643. return enc;
  1644. }
  1645. export function utf8Encode(string) {
  1646. string = (string + '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
  1647. let utftext = '',
  1648. start,
  1649. end;
  1650. let stringl = 0,
  1651. n;
  1652. start = end = 0;
  1653. stringl = string.length;
  1654. for (n = 0; n < stringl; n++) {
  1655. let c1 = string.charCodeAt(n);
  1656. let enc = null;
  1657. if (c1 < 128) {
  1658. end++;
  1659. } else if ((c1 > 127) && (c1 < 2048)) {
  1660. enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128);
  1661. } else {
  1662. enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
  1663. }
  1664. if (enc !== null) {
  1665. if (end > start) {
  1666. utftext += string.substring(start, end);
  1667. }
  1668. utftext += enc;
  1669. start = end = n + 1;
  1670. }
  1671. }
  1672. if (end > start) {
  1673. utftext += string.substring(start, string.length);
  1674. }
  1675. return utftext;
  1676. }
  1677. /*
  1678. * 富文本内容反转义(接口返回的富文本内容经过了转义,导致内容无法展示,所以需要反转义)
  1679. * @param {String} str 富文本内容
  1680. * */
  1681. export function quillEscapeToHtml(str) {
  1682. if(str!=undefined&&str){
  1683. const arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' }
  1684. return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function(all, t) {
  1685. return arrEntities[t]
  1686. })
  1687. }else{
  1688. return ''
  1689. }
  1690. }
  1691. /*
  1692. * 关闭当前浏览器窗口
  1693. * */
  1694. export function pageClose() {
  1695. if (navigator.userAgent.indexOf("MSIE") > 0) {
  1696. if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
  1697. window.opener = null;
  1698. window.close();
  1699. } else {
  1700. window.open('', '_top');
  1701. window.top.close();
  1702. }
  1703. }
  1704. else if (navigator.userAgent.indexOf("Firefox") > 0) {
  1705. window.location.href = 'about:blank ';
  1706. } else {
  1707. window.opener = null;
  1708. window.open('', '_self', '');
  1709. window.close();
  1710. }
  1711. }
  1712. /**
  1713. * 上传视频限制,限制的大小是服务器的配置
  1714. */
  1715. export function sldBeforeUploadVideo(file, fileList, limit = uploadLimit) {
  1716. if (file.type.indexOf('mp4')>-1) {
  1717. if (file.size != undefined && file.size > 1024 * 1024 * limit) {
  1718. failTip(`上传视频过大,请上传小于${limit}M的视频`);
  1719. return false;
  1720. }
  1721. } else{
  1722. failTip(`请上传mp4格式的视频`);
  1723. return false;
  1724. }
  1725. }
  1726. export const webSiteContactRelation = {
  1727. '1': 'email', // 海外用户
  1728. '2': 'mobile' // 国内分销商
  1729. }