12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531
  1. <?php
  2. error_reporting(E_ERROR | E_PARSE);
  3. /**
  4. * 行为绑定
  5. */
  6. \think\Hook::add('app_init', 'app\\common\\behavior\\InitConfigBehavior');
  7. use app\common\adapter\AuthAdapter;
  8. use app\admin\model\User as UserModel;
  9. use app\admin\model\Field as FieldModel;
  10. use think\Request;
  11. use think\Db;
  12. use extend\email\Email;
  13. use think\Lang;
  14. use think\helper\Time;
  15. use com\IpLocation;
  16. use app\crm\traits\DataTime;
  17. /**
  18. * 对象 转 数组
  19. *
  20. * @param object $obj 对象
  21. * @return array
  22. */
  23. function object_to_array($obj)
  24. {
  25. $obj = (array)$obj;
  26. foreach ($obj as $k => $v) {
  27. if (gettype($v) == 'resource') {
  28. return;
  29. }
  30. if (gettype($v) == 'object' || gettype($v) == 'array') {
  31. $obj[$k] = (array)object_to_array($v);
  32. }
  33. }
  34. return $obj;
  35. }
  36. /**
  37. * 数组 转 对象
  38. *
  39. * @param array $arr 数组
  40. * @return object
  41. */
  42. function array_to_object($arr)
  43. {
  44. if (gettype($arr) != 'array') {
  45. return;
  46. }
  47. foreach ($arr as $k => $v) {
  48. if (gettype($v) == 'array' || getType($v) == 'object') {
  49. $arr[$k] = (object)array_to_object($v);
  50. }
  51. }
  52. return (object)$arr;
  53. }
  54. /**
  55. * 返回对象
  56. * @param array $array 响应数据
  57. */
  58. function resultArray($array)
  59. {
  60. if (isset($array['data'])) {
  61. $array['error'] = '';
  62. $code = 200;
  63. } elseif (is_array($array['error'])) {
  64. $code = 402; //返回数组格式
  65. $array['data'] = '';
  66. } elseif (isset($array['error'])) {
  67. $code = 400;
  68. $array['data'] = '';
  69. }
  70. return json([
  71. 'code' => $code,
  72. 'data' => $array['data'],
  73. 'error' => $array['error']
  74. ]);
  75. }
  76. /**
  77. * 调试方法
  78. * @param array $data [description]
  79. */
  80. function p($data, $die = 1)
  81. {
  82. echo "<pre>";
  83. print_r($data);
  84. echo "</pre>";
  85. if ($die) die;
  86. }
  87. /**
  88. * 用户密码加密方法
  89. * @param string $str 加密的字符串
  90. * @param [type] $auth_key 加密符
  91. * @param [string] $username 用户名
  92. * @return string 加密后长度为32的字符串
  93. */
  94. function user_md5($str, $auth_key = '', $username = '')
  95. {
  96. return '' === $str ? '' : md5(sha1($str) . md5($str . $auth_key));
  97. }
  98. /**
  99. * 金额展示规则,超过1万时以万为单位,低于1万时以千为单位,低于1千时以元为单位
  100. * @param string $money 金额
  101. * @return string
  102. * @author Michael_xu
  103. */
  104. function money_view($money)
  105. {
  106. $data = '0元';
  107. if (($money / 10000) > 1) {
  108. $data = is_int($money / 10000) ? ($money / 10000) . '万' : rand(($money / 10000), 2) . '万';
  109. } elseif (($money / 1000) > 1) {
  110. $data = is_int($money / 1000) ? ($money / 1000) . '千' : rand(($money / 1000), 2) . '千';
  111. } else {
  112. $data = $money . '元';
  113. }
  114. return $data;
  115. }
  116. /**
  117. * 高级筛选条件
  118. * @param $array 条件数组
  119. * @param $module 相关模块
  120. * @return string
  121. * @author Michael_xu
  122. */
  123. function where_arr($array = [], $m = '', $c = '', $a = '')
  124. {
  125. $userModel = new UserModel();
  126. $checkStatusList = ['待审核', '审核中', '审核通过', '审核失败', '已撤回', '未提交', '已作废'];
  127. $checkStatusArray = ['待审核' => 0, '审核中' => 1, '审核通过' => 2, '审核失败' => 3, '已撤回' => 4, '未提交' => 5, '已作废' => 6];
  128. //查询自定义字段模块多选字段类型
  129. $check_field_arr = [];
  130. //特殊字段
  131. //过滤系统参数
  132. $unset_arr = ['page', 'limit', 'order_type', 'order_field'];
  133. if (!is_array($array)) {
  134. return [];
  135. }
  136. $types = $c;
  137. foreach ($array as $k => $v) {
  138. if (!in_array($k, $unset_arr)) {
  139. $c = $types . '.';
  140. if ($k == 'customer_name') {
  141. $k = 'name';
  142. $c = 'customer.';
  143. }
  144. if ($k == 'contract_name') {
  145. $k = 'name';
  146. $c = 'contract.';
  147. }
  148. if ($k == 'business_name') {
  149. $k = 'name';
  150. $c = 'business.';
  151. }
  152. if ($k == 'contacts_name') {
  153. $k = 'name';
  154. $c = 'contacts.';
  155. }
  156. if ($v['form_type'] == 'date') {
  157. if (!empty($v['start'])) $v['start'] = date('Y-m-d', $v['start']);
  158. if (!empty($v['end'])) $v['end'] = date('Y-m-d', $v['end']);
  159. }
  160. # 创建人、负责人、回访人(非自定义字段)
  161. // if ($v['form_type'] == 'user' && in_array($k, ['create_user_id', 'owner_user_id'])) {
  162. // if ($v['condition'] == 'is') $v['condition'] = 'contains';
  163. // }
  164. # 自定义字段的user、structure类型
  165. if (($v['form_type'] == 'user' && !in_array($k, ['create_user_id', 'owner_user_id'])) || $v['form_type'] == 'structure') {
  166. if ($v['condition'] == 'is') $v['condition'] = 'contains';
  167. if ($v['condition'] == 'isNot') {
  168. return "(" . $c . $k . " not like ',%" . $v['value'][0] . "%,' OR " . $c . $k . " is null)";
  169. }
  170. }
  171. # 处理多选字段的精确搜索
  172. if ($v['form_type'] == 'checkbox' && !empty($v['value'])) {
  173. if ($v['condition'] == 'is' && count($v['value']) == 1) $v['value'][0] = ',' . $v['value'][0] . ',';
  174. if ($v['condition'] == 'is' && count($v['value']) > 1) {
  175. $checkboxLike = '';
  176. foreach ($v['value'] as $kk => $vv) {
  177. $checkboxLike .= $c . $k . " like " . "',%" . $vv . "%,' AND ";
  178. }
  179. return "(" . $checkboxLike . "LENGTH(" . $c . $k . ") = LENGTH('" . arrayToString($v['value']) . "'))";
  180. }
  181. }
  182. if ($types == 'contract' && !empty($v['value'])) {
  183. switch ($k) {
  184. case 'business_id' :
  185. $k = 'name';
  186. $c = 'business.';
  187. break;
  188. case 'contacts_id' :
  189. $contactsIds = [];
  190. foreach ($v['value'] as $kk => $vv) {
  191. $contactsIdArray = db('crm_contacts')->whereLike('name', '%' . $vv . '%')->column('contacts_id');
  192. foreach ($contactsIdArray as $kkk => $vvv) {
  193. $contactsIds[] = $vvv;
  194. }
  195. }
  196. $v['value'] = array_unique($contactsIds);
  197. break;
  198. }
  199. }
  200. if ($types == 'receivables' && $v['name'] == '合同编号' && !empty($v['value'])) {
  201. $k = 'num';
  202. $c = 'contract.';
  203. }
  204. if ($types == 'receivables' && $k == 'plan_id' && !empty($v['value'])) {
  205. $planIds = [];
  206. foreach ($v['value'] as $kk => $vv) {
  207. $planIdArray = db('crm_receivables_plan')->whereLike('num', '%' . $vv . '%')->column('plan_id');
  208. foreach ($planIdArray as $kkk => $vvv) {
  209. $planIds[] = $vvv;
  210. }
  211. }
  212. $v['value'] = array_unique($planIds);
  213. }
  214. if ($types == 'invoice' && $v['type'] == 'invoice_status' && !empty($v['value'])) {
  215. foreach ($v['value'] as $kk => $vv) {
  216. if ($vv == '已开票') $v['value'][$kk] = 1;
  217. if ($vv == '未开票') $v['value'][$kk] = 0;
  218. }
  219. }
  220. if ($types == 'visit' && $v['type'] == 'contract_name' && !empty($v['value'])) {
  221. $k = 'num';
  222. $c = 'contract.';
  223. }
  224. if ($types == 'visit' && $v['type'] == 'contacts_name' && !empty($v['value'])) {
  225. $k = 'name';
  226. $c = 'contacts.';
  227. }
  228. if ($k == 'check_status' && is_array($v) && in_array($v['value'][0], $checkStatusList) && !empty($v['value'])) {
  229. $v['value'] = $checkStatusArray[$v['value'][0]] ?: '0';
  230. }
  231. if (is_array($v)) {
  232. if ($v['state']) {
  233. $address_where[] = '%' . $v['state'] . '%';
  234. if ($v['city']) {
  235. $address_where[] = '%' . $v['city'] . '%';
  236. if ($v['area']) {
  237. $address_where[] = '%' . $v['area'] . '%';
  238. }
  239. }
  240. if ($v['condition'] == 'not_contain') {
  241. $where[$c . $k] = ['notlike', $address_where, 'OR'];
  242. } else {
  243. $where[$c . $k] = ['like', $address_where, 'AND'];
  244. }
  245. } elseif (!empty($v['value']['state'])) {
  246. $addressWhere[] = '%' . $v['value']['state'] . '%';
  247. if (!empty($v['value']['city'])) $addressWhere[] = '%' . $v['value']['city'] . '%';
  248. if (!empty($v['value']['area'])) $addressWhere[] = '%' . $v['value']['area'] . '%';
  249. if ($v['condition'] == 'is') {
  250. $where[$c . $k] = ['like', $addressWhere, 'AND'];
  251. } else {
  252. $where[$c . $k] = ['notlike', $addressWhere, 'OR'];
  253. }
  254. } elseif (!empty($v['start']) || !empty($v['end'])) {
  255. if ($v['start'] && $v['end']) {
  256. $where[$c . $k] = ['between', [$v['start'], $v['end']]];
  257. } elseif ($v['start']) {
  258. $where[$c . $k] = ['egt', $v['start']];
  259. } else {
  260. $where[$c . $k] = ['elt', $v['end']];
  261. }
  262. } elseif (!empty($v['start_date']) || !empty($v['end_date'])) {
  263. if ($v['start_date'] && $v['end_date']) {
  264. $where[$c . $k] = ['between', [$v['start_date'], $v['end_date']]];
  265. } elseif ($v['start_date']) {
  266. $where[$c . $k] = ['egt', $v['start_date']];
  267. } else {
  268. $where[$c . $k] = ['elt', $v['end_date']];
  269. }
  270. } elseif (!empty($v['value']) || $v['value'] === '0') {
  271. if (in_array($k, $check_field_arr)) {
  272. $where[$c . $k] = field($v['value'], 'contains');
  273. } else {
  274. if ($v['condition'] == 'isNot' || $v['condition'] == 'notContains') {
  275. $where[$c . $k] = [field($v['value'], $v['condition'], $k), ['null'], 'or'];
  276. } else {
  277. $where[$c . $k] = field($v['value'], $v['condition'], $k);
  278. }
  279. }
  280. } elseif (in_array($v['condition'], ['isNull', 'isNotNull', 'in'])) {
  281. $where[$c . $k] = field($v['value'], $v['condition']);
  282. } else {
  283. $where[$c . $k] = $v;
  284. }
  285. } elseif (!empty($v)) {
  286. $where[$c . $k] = field($v);
  287. } else {
  288. $where[$c . $k] = $v;
  289. }
  290. }
  291. }
  292. # 商机阶段为赢单、输单、无效的值保存在is_end中,将status_id改为is_end;
  293. if (!empty($where['business.status_id']) && in_array($where['business.status_id'][1], [1, 2, 3])) {
  294. $where['business.is_end'] = $where['business.status_id'];
  295. unset($where['business.status_id']);
  296. }
  297. return $where ?: [];
  298. }
  299. /**
  300. * 根据搜索生成where条件
  301. *
  302. * @param string $search 搜索内容
  303. * @param $condition 搜索条件
  304. * @param $k 搜索字段
  305. * @return array|Closure|string[]
  306. */
  307. function field($search, $condition = '', $k = '')
  308. {
  309. switch (trim($condition)) {
  310. case "is" :
  311. $where = ['in', $search];
  312. break;
  313. case "isNot" :
  314. $where = ['notin', $search];
  315. break;
  316. case "contains" :
  317. $containsWhere = [];
  318. foreach ((array)$search as $key1 => $value1) $containsWhere[] = '%' . $value1 . '%';
  319. $where = ['like', $containsWhere, 'OR'];
  320. break;
  321. case "notContains" :
  322. $containsWhere = [];
  323. foreach ((array)$search as $key1 => $value1) $containsWhere[] = '%' . $value1 . '%';
  324. $where = ['notlike', $containsWhere, 'AND'];
  325. break;
  326. case "startWith" :
  327. $startWithWhere = [];
  328. foreach ((array)$search as $key1 => $value1) $startWithWhere[] = $value1 . '%';
  329. $where = ['like', $startWithWhere, 'OR'];
  330. break;
  331. case "endWith" :
  332. $endWithWhere = [];
  333. foreach ((array)$search as $key1 => $value1) $endWithWhere[] = '%' . $value1;
  334. $where = ['like', $endWithWhere, 'OR'];
  335. break;
  336. case "isNull" :
  337. $where = ['eq', ''];
  338. break;
  339. case "isNotNull" :
  340. $where = ['neq', ''];
  341. break;
  342. case "eq" :
  343. $where = function ($query) use ($search, $k) {
  344. foreach ((array)$search as $key1 => $value1) {
  345. $query->whereOr($k, $value1);
  346. }
  347. };
  348. break;
  349. case "neq" :
  350. $where = function ($query) use ($search, $k) {
  351. foreach ((array)$search as $key1 => $value1) {
  352. $query->whereOr($k, '<>', $value1);
  353. }
  354. };
  355. break;
  356. case "gt" :
  357. $where = function ($query) use ($search, $k) {
  358. foreach ((array)$search as $key1 => $value1) {
  359. $query->whereOr($k, '>', $value1);
  360. }
  361. };
  362. break;
  363. case "egt" :
  364. $where = function ($query) use ($search, $k) {
  365. foreach ((array)$search as $key1 => $value1) {
  366. $query->whereOr($k, '>=', $value1);
  367. }
  368. };
  369. break;
  370. case "lt" :
  371. $where = function ($query) use ($search, $k) {
  372. foreach ((array)$search as $key1 => $value1) {
  373. $query->whereOr($k, '<', $value1);
  374. }
  375. };
  376. break;
  377. case "elt" :
  378. $where = function ($query) use ($search, $k) {
  379. foreach ((array)$search as $key1 => $value1) {
  380. $query->whereOr($k, '<=', $value1);
  381. }
  382. };
  383. break;
  384. case "in" :
  385. $where = ['in', $search];
  386. break;
  387. default :
  388. $where = ['eq', $search];
  389. break;
  390. }
  391. return $where;
  392. }
  393. /**
  394. * 将单个搜索转换为高级搜索格式
  395. * @param string $value 搜索内容
  396. * @param $condition 搜索条件
  397. * @return array
  398. * @author Michael_xu
  399. */
  400. function field_arr($value, $condition = '')
  401. {
  402. if (is_array($value)) {
  403. } else {
  404. $condition = $condition ?: 'eq';
  405. $where_arr = ['value' => $value, 'condition' => $condition];
  406. }
  407. return $where_arr;
  408. }
  409. /**
  410. * 记录操作日志
  411. * @param $id array 操作对象id数组
  412. * @return
  413. * @author Michael_xu
  414. */
  415. function actionLog($id, $join_user_ids = '', $structure_ids = '', $content = '')
  416. {
  417. if (!is_array($id)) {
  418. $idArr[] = $id;
  419. } else {
  420. $idArr = $id;
  421. }
  422. $header = Request::instance()->header();
  423. $authKey = $header['authkey'];
  424. $cache = cache('Auth_' . $authKey);
  425. if (!$cache) {
  426. return false;
  427. }
  428. $userInfo = $cache['userInfo'];
  429. $category = $userInfo['id'] == 1 ? '管理员' : '员工';
  430. $request = request();
  431. $m = strtolower($request->module());
  432. $c = strtolower($request->controller());
  433. $a = strtolower($request->action());
  434. $res_action = true;
  435. foreach ($idArr as $v) {
  436. $data = [];
  437. $data['user_id'] = $userInfo['id'];
  438. $data['module_name'] = $module_name = $m;
  439. $data['controller_name'] = $controller_name = $c;
  440. $data['action_name'] = $action_name = $a;
  441. $data['action_id'] = $v;
  442. $data['create_time'] = time();
  443. $data['client_ip'] = request()->ip();
  444. $data['content'] = $content ?: lang('ACTIONLOG', [$category, $userInfo['realname'], date('Y-m-d H:i:s'), lang($action_name), $v, lang($controller_name)]);
  445. $data['join_user_ids'] = $join_user_ids ?: ''; //抄送人
  446. $data['structure_ids'] = $structure_ids ?: ''; //抄送部门
  447. if ($action_name == 'delete' || $action_name == 'commentdel') {
  448. $data['action_delete'] = 1;
  449. }
  450. if (!db('admin_action_log')->insert($data)) {
  451. $res_action = false;
  452. }
  453. # 数据操作日志
  454. db('admin_operation_log')->insert([
  455. 'user_id' => $userInfo['id'],
  456. 'client_ip' => request()->ip(),
  457. 'module' => $m . '_' . $c,
  458. 'action_id' => $v,
  459. 'content' => $content,
  460. 'create_time' => time()
  461. ]);
  462. }
  463. if ($res_action) {
  464. return true;
  465. } else {
  466. return false;
  467. }
  468. }
  469. /**
  470. * 判断操作权限
  471. * @param
  472. * @return
  473. * @author Michael_xu
  474. */
  475. function checkPerByAction($m, $c, $a)
  476. {
  477. /*获取头部信息*/
  478. $header = Request::instance()->header();
  479. $authKey = $header['authkey'];
  480. $cache = cache('Auth_' . $authKey);
  481. if (!$cache) {
  482. return false;
  483. }
  484. $userInfo = $cache['userInfo'];
  485. $adminTypes = adminGroupTypes($userInfo['id']);
  486. if (in_array(1, $adminTypes)) {
  487. return true;
  488. }
  489. if (empty($m) && empty($c) && empty($a)) {
  490. $request = Request::instance();
  491. $m = strtolower($request->module());
  492. $c = strtolower($request->controller());
  493. $a = strtolower($request->action());
  494. }
  495. $authAdapter = new AuthAdapter($authKey);
  496. $ruleName = $m . '-' . $c . '-' . $a;
  497. if (!$authAdapter->checkIntime($ruleName, $userInfo['id'])) {
  498. return false;
  499. }
  500. return true;
  501. }
  502. /**
  503. * 给树状菜单添加level并去掉没有子菜单的菜单项
  504. * @param array $data [description]
  505. * @param integer $root [description]
  506. * @param string $child [description]
  507. * @param string $level [description]
  508. */
  509. function memuLevelClear($data, $root = 1, $child = 'children', $level = 'level')
  510. {
  511. if (is_array($data)) {
  512. foreach ($data as $key => $val) {
  513. // $data[$key]['selected'] = false;
  514. $data[$key]['level'] = $root;
  515. if (!empty($val[$child]) && is_array($val[$child])) {
  516. $data[$key][$child] = memuLevelClear($val[$child], $root + 1);
  517. } else if ($root < 3 && $data[$key]['menu_type'] == 1) {
  518. unset($data[$key]);
  519. }
  520. if (empty($data[$key][$child]) && ($data[$key]['level'] == 1) && ($data[$key]['menu_type'] == 1)) {
  521. unset($data[$key]);
  522. }
  523. }
  524. return array_values($data);
  525. }
  526. return array();
  527. }
  528. /**
  529. * [rulesDeal 给树状规则表处理成 module-controller-action ]
  530. * @AuthorHTL
  531. * @DateTime
  532. * @param [array] $data [树状规则数组]
  533. * @return [array] [返回数组]
  534. */
  535. function rulesDeal($data)
  536. {
  537. if (is_array($data)) {
  538. $ret = [];
  539. foreach ($data as $k1 => $v1) {
  540. $str1 = $v1['name'];
  541. if (is_array($v1['children'])) {
  542. foreach ($v1['children'] as $k2 => $v2) {
  543. $str2 = $str1 . '-' . $v2['name'];
  544. if (is_array($v2['children'])) {
  545. foreach ($v2['children'] as $k3 => $v3) {
  546. $str3 = $str2 . '-' . $v3['name'];
  547. $ret[] = $str3;
  548. }
  549. } else {
  550. $ret[] = $str2;
  551. }
  552. }
  553. } else {
  554. $ret[] = $str1;
  555. }
  556. }
  557. return $ret;
  558. }
  559. return [];
  560. }
  561. /**
  562. * 获取下属userId
  563. * @param $self == true 包含自己
  564. * @param $type == 0 下属userid
  565. * @param $type == 1 全部userid
  566. * @param $user_id 需要查询的user_id
  567. * @author Michael_xu
  568. */
  569. function getSubUserId($self = true, $type = 0, $user_id = '')
  570. {
  571. $request = Request::instance();
  572. $header = $request->header();
  573. $authKey = $header['authkey'];
  574. $cache = cache('Auth_' . $authKey);
  575. if (!$user_id) {
  576. if (!$cache) {
  577. return false;
  578. }
  579. $userInfo = $cache['userInfo'];
  580. $user_id = $userInfo['id'];
  581. $adminTypes = adminGroupTypes($user_id);
  582. if (in_array(1, $adminTypes)) {
  583. $type = 1;
  584. }
  585. }
  586. $belowIds = [];
  587. if (empty($type)) {
  588. if ($user_id) {
  589. $belowIds = getSubUser($user_id);
  590. }
  591. } else {
  592. $belowIds = getSubUser(0);
  593. }
  594. if ($self == true) {
  595. $belowIds[] = $user_id;
  596. } else {
  597. $belowIds = $belowIds ? array_diff($belowIds, array($user_id)) : [];
  598. }
  599. return array_unique($belowIds);
  600. }
  601. /**
  602. * 获取下属userId
  603. * @author Michael_xu
  604. */
  605. function getSubUser($userId, $queried = [], $allUserList = [])
  606. {
  607. if (empty($allUserList)) {
  608. $allUserList = db('admin_user')->field('id,parent_id')->select();
  609. }
  610. foreach ($allUserList as $k => $v) {
  611. if ($v['parent_id'] == $userId) {
  612. $sub_user[] = $v['id'];
  613. }
  614. }
  615. if ($sub_user) {
  616. foreach ($sub_user as $v) {
  617. if (in_array($v, $queried)) {
  618. continue;
  619. }
  620. $queried[] = $v;
  621. $son_user = [];
  622. $son_user = getSubUser($v, $queried, $allUserList);
  623. if (!empty($son_user)) {
  624. $sub_user = array_merge($sub_user, $son_user);
  625. }
  626. }
  627. }
  628. return $sub_user;
  629. }
  630. /**
  631. * 阿里大于短信发送
  632. * @param unknown $appkey
  633. * @param unknown $secret
  634. * @param unknown $signName 短信签名
  635. * @param unknown $smsParam
  636. * @param unknown $templateCode 短信模板
  637. * @param unknown $send_mobile 接收手机号
  638. * @param unknown $code 短信验证码
  639. * @param unknown $template_code 模板参数
  640. */
  641. function aliSmsSend($send_mobile, $code, $signName, $templateCode)
  642. {
  643. $appkey = '';
  644. $secret = '';
  645. import('alimsg.api.Sms', EXTEND_PATH);
  646. header('Content-Type: text/plain; charset=utf-8');
  647. $sms = new Sms($appkey, $secret);
  648. $template_code = array("code" => $code);
  649. $response = $sms->sendSms($signName, $templateCode, $send_mobile, $template_code);
  650. $data = object_to_array($response);
  651. if ($data['Message'] == 'OK' && $data['Code'] == "OK") {
  652. return true;
  653. } else {
  654. return false;
  655. }
  656. }
  657. /**
  658. * 发送邮件
  659. * @param unknown $toemail
  660. * @param unknown $title
  661. * @param unknown $content
  662. * @return boolean
  663. */
  664. function emailSend($email_host, $email_id, $email_pass, $email_addr, $toemail, $title, $content)
  665. {
  666. $result = false;
  667. try {
  668. $mail = new Email();
  669. $mail->setServer($email_host, $email_id, $email_pass);
  670. $mail->setFrom($email_addr);
  671. $mail->setReceiver($toemail);
  672. $mail->setMailInfo($title, $content);
  673. $result = $mail->sendMail();
  674. } catch (\Exception $e) {
  675. $result = false;
  676. }
  677. return $result;
  678. }
  679. /**
  680. * 发送站内信
  681. * @param $user_id 接收人user_id
  682. * @param $action_id 操作id
  683. * @param $sysMessage 1为系统消息
  684. * @param $content 消息内容
  685. * @return
  686. * @author Michael_xu
  687. */
  688. function sendMessage($user_id, $content, $action_id, $sysMessage = 0)
  689. {
  690. $content = trim($content);
  691. if (!$user_id) return false;
  692. if (!$content) return false;
  693. if (!is_array($user_id)) {
  694. $user_ids[] = $user_id;
  695. } else {
  696. $user_ids = $user_id;
  697. }
  698. $user_ids = array_unique(array_filter($user_ids));
  699. $request = request();
  700. $m = strtolower($request->module());
  701. $c = strtolower($request->controller());
  702. $a = strtolower($request->action());
  703. $userInfo = [];
  704. if ($sysMessage == 0) {
  705. $header = $request->header();
  706. $authkey = $header['authkey'];
  707. $cache = cache('Auth_' . $authkey);
  708. if (!$cache) {
  709. return false;
  710. }
  711. $userInfo = $cache['userInfo'];
  712. }
  713. foreach ($user_ids as $v) {
  714. $data = [];
  715. $data['content'] = $content;
  716. $data['from_user_id'] = $userInfo['id'] ?: 0;
  717. $data['to_user_id'] = $v;
  718. $data['read_time'] = 0;
  719. $data['send_time'] = time();
  720. $data['module_name'] = $m;
  721. $data['controller_name'] = $c;
  722. $data['action_name'] = $a;
  723. $data['action_id'] = $action_id;
  724. db('admin_message')->insert($data);
  725. }
  726. return true;
  727. }
  728. /**
  729. * 格式化字节大小
  730. * @param number $size 字节数
  731. * @param string $delimiter 数字和单位分隔符
  732. * @return string 格式化后的带单位的大小
  733. * @author
  734. */
  735. function format_bytes($size, $delimiter = '')
  736. {
  737. $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
  738. for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
  739. return round($size, 2) . $delimiter . $units[$i];
  740. }
  741. /**
  742. * 数据修改日志
  743. * @param $types 类型
  744. * @param $action_id 操作ID
  745. * @param $newData 新数据
  746. * @param $newData 新数据
  747. * @return
  748. * @author Michael_xu
  749. */
  750. function updateActionLog($user_id, $types, $action_id, $oldData = [], $newData = [], $content = '')
  751. {
  752. # 转格式
  753. if (!empty($oldData['next_time']) && $oldData['next_time'] != strtotime($oldData['next_time'])) {
  754. $oldData['next_time'] = strtotime($oldData['next_time']);
  755. }
  756. if (is_array($oldData) && is_array($newData) && $user_id) {
  757. $differentData = array_diff_assoc($newData, $oldData);
  758. $fieldModel = new FieldModel();
  759. $userModel = new UserModel();
  760. $structureModel = new \app\admin\model\Structure();
  761. $field_arr = $fieldModel->getField(['types' => $types, 'unFormType' => ['file', 'form']]); //获取字段属性
  762. $newFieldArr = array();
  763. foreach ($field_arr as $k => $v) {
  764. $newFieldArr[$v['field']] = $v;
  765. }
  766. $unField = ['update_time', 'create_time']; //定义过滤字段
  767. $message = [];
  768. $un_form_type = ['file', 'form'];
  769. foreach ($differentData as $k => $v) {
  770. if ($newFieldArr[$k] && !in_array($newFieldArr[$k]['form_type'], $un_form_type)) {
  771. $field_name = '';
  772. $field_name = $newFieldArr[$k]['name'];
  773. $new_value = $v ?: '空';
  774. $old_value = $oldData[$k] ?: '空';
  775. if ($newFieldArr[$k]['form_type'] == 'datetime') {
  776. $new_value = $v ? date('Y-m-d', $v) : '空';
  777. $old_value = !empty($oldData[$k]) ? date('Y-m-d', $oldData[$k]) : '空';
  778. if (empty($v) && empty($oldData[$k])) continue;
  779. } elseif ($newFieldArr[$k]['form_type'] == 'user') {
  780. $new_value = $v ? implode(',', $userModel->getUserNameByArr(stringToArray($v))) : '';
  781. $old_value = $v ? implode(',', $userModel->getUserNameByArr(stringToArray($oldData[$k]))) : '';
  782. } elseif ($newFieldArr[$k]['form_type'] == 'structure') {
  783. $new_value = $v ? implode(',', $structureModel->getStructureNameByArr(stringToArray($v))) : '';
  784. $old_value = $v ? implode(',', $structureModel->getStructureNameByArr(stringToArray($oldData[$k]))) : '';
  785. } elseif ($newFieldArr[$k]['form_type'] == 'business_status') {
  786. $new_value = $v ? db('crm_business_status')->where(['status_id' => $v])->value('name') : '';
  787. $old_value = $v ? db('crm_business_status')->where(['status_id' => $oldData[$k]])->value('name') : '';
  788. } elseif ($newFieldArr[$k]['form_type'] == 'business_type') {
  789. $new_value = $v ? db('crm_business_type')->where(['type_id' => $v])->value('name') : '';
  790. $old_value = $v ? db('crm_business_type')->where(['type_id' => $oldData[$k]])->value('name') : '';
  791. } elseif ($newFieldArr[$k]['form_type'] == 'customer') {
  792. $new_value = $v ? db('crm_customer')->where(['customer_id' => $v])->value('name') : '';
  793. $old_value = $v ? db('crm_customer')->where(['customer_id' => $oldData[$k]])->value('name') : '';
  794. } elseif ($newFieldArr[$k]['form_type'] == 'category') {
  795. $new_value = $v ? db('crm_product_category')->where(['category_id' => $v])->value('name') : '';
  796. $old_value = $v ? db('crm_product_category')->where(['category_id' => $oldData[$k]])->value('name') : '';
  797. } elseif ($newFieldArr[$k]['form_type'] == 'business') {
  798. $new_value = $v ? db('crm_business')->where(['business_id' => $v])->value('name') : '';
  799. $old_value = $v ? db('crm_business')->where(['business_id' => $oldData[$k]])->value('name') : '';
  800. } elseif ($newFieldArr[$k]['field'] == 'check_status') {
  801. $statusArr = ['0' => '待审核', '1' => '审核中', '2' => '审核通过', '3' => '已拒绝', '4' => '已撤回', '5' => '未提交'];
  802. $new_value = $statusArr[$v];
  803. $old_value = $statusArr[$oldData[$k]];
  804. } elseif ($newFieldArr[$k]['form_type'] == 'visit') {
  805. $new_value = $v ? db('crm_visit')->where(['visit_id' => $v])->value('number') : '';
  806. $old_value = $v ? db('crm_visit')->where(['visit_id' => $oldData[$k]])->value('number') : '';
  807. } elseif ($newFieldArr[$k]['form_type'] == 'single_user') {
  808. $new_value = $v ? db('admin_user')->where(['id' => $v])->value('realname') : '';
  809. $old_value = $v ? db('admin_user')->where(['id' => $oldData['owner_user_id']])->value('realname') : '';
  810. } elseif ($newFieldArr[$k]['form_type'] == 'floatnumber') {
  811. $new_value = $v ? number_format($v, 2) : '';
  812. }
  813. if ($old_value != $new_value) {
  814. $message[] = '将 ' . "'" . $field_name . "'" . ' 由 ' . $old_value . ' 修改为 ' . $new_value;
  815. }
  816. }
  817. }
  818. if ($message) {
  819. $data = [];
  820. $data['user_id'] = $user_id;
  821. $data['create_time'] = time();
  822. $data['types'] = $types;
  823. $data['action_id'] = $action_id;
  824. $data['content'] = implode('.|.', $message);
  825. db('admin_action_record')->insert($data);
  826. }
  827. } elseif ($content) {
  828. $data = [];
  829. $data['user_id'] = $user_id;
  830. $data['create_time'] = time();
  831. $data['types'] = $types;
  832. $data['action_id'] = $action_id;
  833. $data['content'] = $content;
  834. db('admin_action_record')->insert($data);
  835. }
  836. }
  837. /**
  838. * 截取字符串
  839. * @param $start 开始截取位置
  840. * @param $length 截取长度
  841. * @return
  842. * @author Michael_xu
  843. */
  844. function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
  845. {
  846. if (function_exists("mb_substr")) {
  847. $slice = mb_substr($str, $start, $length, $charset);
  848. } elseif (function_exists('iconv_substr')) {
  849. $slice = iconv_substr($str, $start, $length, $charset);
  850. if (false === $slice) {
  851. $slice = '';
  852. }
  853. } else {
  854. $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
  855. $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
  856. $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
  857. $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
  858. preg_match_all($re[$charset], $str, $match);
  859. $slice = join("", array_slice($match[0], $start, $length));
  860. }
  861. if (utf8_strlen($str) < $length) $suffix = false;
  862. return $suffix ? $slice . '...' : $slice;
  863. }
  864. function utf8_strlen($string = null)
  865. {
  866. preg_match_all("/./us", $string, $match);
  867. return count($match[0]);
  868. }
  869. /**
  870. * 合法性验证
  871. * @param client_sign 签名参数值,使用相同规则对提交参数进行加密验证
  872. * @return
  873. * @author Michael_xu
  874. */
  875. function checkVerify($saftCode = '5kcrm@')
  876. {
  877. $parmList = Request::instance()->post();
  878. $header = $request->header();
  879. $parmList['sessionId'] = $header['sessionId'];
  880. $authkey = $header['authKey'];
  881. $clientSign = $parmList['client_sign'];
  882. if ($clientSign) {
  883. unset($parmList['client_sign']);
  884. if (count($parmList) > 0) {
  885. // 对要签名参数按照签名格式组合
  886. foreach ($parmList as $key => $value) {
  887. if (isset($_POST[$key])) {
  888. $parame[$key] = $key . '=' . trim($_POST[$key]);
  889. } else {
  890. return false;
  891. }
  892. }
  893. ksort($parame); //参数排序
  894. $returnValue = implode("&", $parame); //拼接字符串
  895. if ($returnValue) {
  896. //base64加密
  897. $signCalc = base64_encode(hash_hmac("sha1", $returnValue, $saftCode . $authkey, $raw_output = false));
  898. // 检查参数签名是否一致
  899. if (trim($clientSign) != trim($signCalc)) {
  900. return false;
  901. } else {
  902. return true;
  903. }
  904. } else {
  905. return false;
  906. }
  907. } else {
  908. return false;
  909. }
  910. } else {
  911. //签名认证错误
  912. return false;
  913. }
  914. }
  915. /**
  916. * 数组转换字符串(以逗号隔开)
  917. * @param
  918. * @return
  919. * @author Michael_xu
  920. */
  921. function arrayToString($array)
  922. {
  923. if (!is_array($array)) {
  924. $data_arr[] = $array;
  925. } else {
  926. $data_arr = $array;
  927. }
  928. $data_arr = array_filter($data_arr); //数组去空
  929. $data_arr = array_unique($data_arr); //数组去重
  930. $data_arr = array_merge($data_arr);
  931. $string = $data_arr ? ',' . implode(',', $data_arr) . ',' : '';
  932. return $string ?: '';
  933. }
  934. /**
  935. * 字符串转换数组(以逗号隔开)
  936. * @param
  937. * @return
  938. * @author Michael_xu
  939. */
  940. function stringToArray($string)
  941. {
  942. if (is_array($string)) {
  943. $data_arr = array_unique(array_filter($string));
  944. } else {
  945. $data_arr = $string ? array_unique(array_filter(explode(',', $string))) : [];
  946. }
  947. $data_arr = $data_arr ? array_merge($data_arr) : [];
  948. return $data_arr ?: [];
  949. }
  950. /**
  951. * 根据时间戳获取星期几
  952. * @param $time 要转换的时间戳
  953. */
  954. function getTimeWeek($time, $i = 0)
  955. {
  956. $weekarray = array("日", "一", "二", "三", "四", "五", "六");
  957. $oneD = 24 * 60 * 60;
  958. return "星期" . $weekarray[date("w", $time + $oneD * $i)];
  959. }
  960. /**
  961. * 二维数组排序(选择)
  962. * @param $select 要进行排序的select结果集
  963. * @param $field 排序的字段
  964. * @param $order 排序方式1降序2升序
  965. */
  966. function sort_select($select = array(), $field, $order = 1)
  967. {
  968. $count = count($select);
  969. if ($order == 1) {
  970. for ($i = 0; $i < $count; $i++) {
  971. $k = $i;
  972. for ($j = $i; $j < $count; $j++) {
  973. if ($select[$k][$field] < $select[$j][$field]) {
  974. $k = $j;
  975. }
  976. }
  977. $temp = $select[$i];
  978. $select[$i] = $select[$k];
  979. $select[$k] = $temp;
  980. }
  981. return $select;
  982. } else {
  983. for ($i = 0; $i < $count; $i++) {
  984. $k = $i;
  985. for ($j = $i; $j < $count; $j++) {
  986. if ($select[$k][$field] > $select[$j][$field]) {
  987. $k = $j;
  988. }
  989. }
  990. $temp = $select[$i];
  991. $select[$i] = $select[$k];
  992. $select[$k] = $temp;
  993. }
  994. return $select;
  995. }
  996. }
  997. /**
  998. * 将秒数转换为时间 (年、天、小时、分、秒)
  999. * @param
  1000. */
  1001. function getTimeBySec($time)
  1002. {
  1003. if (is_numeric($time)) {
  1004. $value = array(
  1005. "years" => 0, "days" => 0, "hours" => 0,
  1006. "minutes" => 0, "seconds" => 0,
  1007. );
  1008. if ($time >= 31556926) {
  1009. $value["years"] = floor($time / 31556926);
  1010. $time = ($time % 31556926);
  1011. $t .= $value["years"] . "年";
  1012. }
  1013. if ($time >= 86400) {
  1014. $value["days"] = floor($time / 86400);
  1015. $time = ($time % 86400);
  1016. $t .= $value["days"] . "天";
  1017. }
  1018. if ($time >= 3600) {
  1019. $value["hours"] = floor($time / 3600);
  1020. $time = ($time % 3600);
  1021. $t .= $value["hours"] . "小时";
  1022. }
  1023. if ($time >= 60) {
  1024. $value["minutes"] = floor($time / 60);
  1025. $time = ($time % 60);
  1026. $t .= $value["minutes"] . "分钟";
  1027. }
  1028. if ($time < 60) {
  1029. $value["seconds"] = floor($time);
  1030. $t .= $value["seconds"] . "秒";
  1031. }
  1032. return $t;
  1033. } else {
  1034. return (bool)FALSE;
  1035. }
  1036. }
  1037. /*
  1038. *根据年月计算有几天
  1039. */
  1040. function getmonthByYM($param)
  1041. {
  1042. $month = $param['month'] ? $param['month'] : date('m', time());
  1043. $year = $param['year'] ? $param['year'] : date('Y', time());
  1044. if (in_array($month, array('1', '3', '5', '7', '8', '01', '03', '05', '07', '08', '10', '12'))) {
  1045. $days = '31';
  1046. } elseif ($month == 2) {
  1047. if ($year % 400 == 0 || ($year % 4 == 0 && $year % 100 !== 0)) {
  1048. //判断是否是闰年
  1049. $days = '29';
  1050. } else {
  1051. $days = '28';
  1052. }
  1053. } else {
  1054. $days = '30';
  1055. }
  1056. return $days;
  1057. }
  1058. /**
  1059. * 根据时间戳计算当月天数
  1060. * @param
  1061. */
  1062. function getmonthdays($time)
  1063. {
  1064. $month = date('m', $time);
  1065. $year = date('Y', $time);
  1066. if (in_array($month, array('1', '3', '5', '7', '8', '01', '03', '05', '07', '08', '10', '12'))) {
  1067. $days = '31';
  1068. } elseif ($month == 2) {
  1069. if ($year % 400 == 0 || ($year % 4 == 0 && $year % 100 !== 0)) {
  1070. //判断是否是闰年
  1071. $days = '29';
  1072. } else {
  1073. $days = '28';
  1074. }
  1075. } else {
  1076. $days = '30';
  1077. }
  1078. return $days;
  1079. }
  1080. /**
  1081. * 生成从开始时间到结束时间的日期数组
  1082. * @param type,默认时间戳格式
  1083. * @param type = 1 时,date格式
  1084. * @param type = 2 时,获取每日开始、结束时间
  1085. */
  1086. function dateList($start, $end, $type = 0)
  1087. {
  1088. if (!is_numeric($start) || !is_numeric($end) || ($end <= $start)) return '';
  1089. $i = 0;
  1090. //从开始日期到结束日期的每日时间戳数组
  1091. $d = array();
  1092. if ($type == 1) {
  1093. while ($start <= $end) {
  1094. $d[$i] = date('Y-m-d', $start);
  1095. $start = $start + 86400;
  1096. $i++;
  1097. }
  1098. } else {
  1099. while ($start <= $end) {
  1100. $d[$i] = $start;
  1101. $start = $start + 86400;
  1102. $i++;
  1103. }
  1104. }
  1105. if ($type == 2) {
  1106. $list = array();
  1107. foreach ($d as $k => $v) {
  1108. $list[$k] = getDateRange($v);
  1109. }
  1110. return $list;
  1111. } else {
  1112. return $d;
  1113. }
  1114. }
  1115. /**
  1116. * 获取指定日期开始时间与结束时间
  1117. */
  1118. function getDateRange($timestamp)
  1119. {
  1120. $ret = array();
  1121. $ret['sdate'] = strtotime(date('Y-m-d', $timestamp));
  1122. $ret['edate'] = strtotime(date('Y-m-d', $timestamp)) + 86400;
  1123. return $ret;
  1124. }
  1125. /**
  1126. * 生成从开始月份到结束月份的月份数组
  1127. * @param int $start 开始时间戳
  1128. * @param int $end 结束时间戳
  1129. */
  1130. function monthList($start, $end)
  1131. {
  1132. if (!is_numeric($start) || !is_numeric($end) || ($end <= $start)) return '';
  1133. $start = date('Y-m', $start);
  1134. $end = date('Y-m', $end);
  1135. //转为时间戳
  1136. $start = strtotime($start . '-01');
  1137. $end = strtotime($end . '-01');
  1138. $i = 0;
  1139. $d = array();
  1140. while ($start <= $end) {
  1141. //这里累加每个月的的总秒数 计算公式:上一月1号的时间戳秒数减去当前月的时间戳秒数
  1142. $d[$i] = $start;
  1143. $start += strtotime('+1 month', $start) - $start;
  1144. $i++;
  1145. }
  1146. return $d;
  1147. }
  1148. /**
  1149. * 人民币转大写
  1150. * @param
  1151. */
  1152. function cny($ns)
  1153. {
  1154. static $cnums = array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"),
  1155. $cnyunits = array("圆", "角", "分"),
  1156. $grees = array("拾", "佰", "仟", "万", "拾", "佰", "仟", "亿");
  1157. list($ns1, $ns2) = explode(".", $ns, 2);
  1158. $ns2 = array_filter(array($ns2[1], $ns2[0]));
  1159. $ret = array_merge($ns2, array(implode("", _cny_map_unit(str_split($ns1), $grees)), ""));
  1160. $ret = implode("", array_reverse(_cny_map_unit($ret, $cnyunits)));
  1161. return str_replace(array_keys($cnums), $cnums, $ret);
  1162. }
  1163. function _cny_map_unit($list, $units)
  1164. {
  1165. $ul = count($units);
  1166. $xs = array();
  1167. foreach (array_reverse($list) as $x) {
  1168. $l = count($xs);
  1169. if ($x != "0" || !($l % 4)) {
  1170. $n = ($x == '0' ? '' : $x) . ($units[($l - 1) % $ul]);
  1171. } else {
  1172. $n = is_numeric($xs[0][0]) ? $x : '';
  1173. }
  1174. array_unshift($xs, $n);
  1175. }
  1176. return $xs;
  1177. }
  1178. /**
  1179. * 根据类型获取上一类型时间戳数组
  1180. */
  1181. function getLstTimeByType($type = 'today')
  1182. {
  1183. switch ($type) {
  1184. case 'yesterday' :
  1185. $timeArr = Time::yesterday();
  1186. break;
  1187. case 'week' :
  1188. $timeArr = Time::week();
  1189. break;
  1190. case 'lastWeek' :
  1191. $timeArr = Time::lastWeek();
  1192. break;
  1193. case 'month' :
  1194. $timeArr = Time::month();
  1195. break;
  1196. case 'lastMonth' :
  1197. $timeArr = Time::lastMonth();
  1198. break;
  1199. case 'quarter' :
  1200. //本季度
  1201. $month = date('m');
  1202. if ($month == 1 || $month == 2 || $month == 3) {
  1203. $daterange_start_time = strtotime(date('Y-01-01 00:00:00'));
  1204. $daterange_end_time = strtotime(date("Y-03-31 23:59:59"));
  1205. } elseif ($month == 4 || $month == 5 || $month == 6) {
  1206. $daterange_start_time = strtotime(date('Y-04-01 00:00:00'));
  1207. $daterange_end_time = strtotime(date("Y-06-30 23:59:59"));
  1208. } elseif ($month == 7 || $month == 8 || $month == 9) {
  1209. $daterange_start_time = strtotime(date('Y-07-01 00:00:00'));
  1210. $daterange_end_time = strtotime(date("Y-09-30 23:59:59"));
  1211. } else {
  1212. $daterange_start_time = strtotime(date('Y-10-01 00:00:00'));
  1213. $daterange_end_time = strtotime(date("Y-12-31 23:59:59"));
  1214. }
  1215. $timeArr = array($daterange_start_time, $daterange_end_time);
  1216. break;
  1217. case 'lastQuarter' :
  1218. //上季度
  1219. $month = date('m');
  1220. if ($month == 1 || $month == 2 || $month == 3) {
  1221. $year = date('Y') - 1;
  1222. $daterange_start_time = strtotime(date($year . '-10-01 00:00:00'));
  1223. $daterange_end_time = strtotime(date($year . '-12-31 23:59:59'));
  1224. } elseif ($month == 4 || $month == 5 || $month == 6) {
  1225. $daterange_start_time = strtotime(date('Y-01-01 00:00:00'));
  1226. $daterange_end_time = strtotime(date("Y-03-31 23:59:59"));
  1227. } elseif ($month == 7 || $month == 8 || $month == 9) {
  1228. $daterange_start_time = strtotime(date('Y-04-01 00:00:00'));
  1229. $daterange_end_time = strtotime(date("Y-06-30 23:59:59"));
  1230. } else {
  1231. $daterange_start_time = strtotime(date('Y-07-01 00:00:00'));
  1232. $daterange_end_time = strtotime(date("Y-09-30 23:59:59"));
  1233. }
  1234. $timeArr = array($daterange_start_time, $daterange_end_time);
  1235. break;
  1236. case 'year' :
  1237. $timeArr = Time::year();
  1238. break;
  1239. case 'lastYear' :
  1240. $timeArr = Time::lastYear();
  1241. break;
  1242. default :
  1243. $timeArr = Time::today();
  1244. break;
  1245. }
  1246. return $timeArr;
  1247. }
  1248. /**
  1249. * 根据类型获取开始结束时间戳数组
  1250. * @param
  1251. */
  1252. function getTimeByType($type = 'today', $is_last = false)
  1253. {
  1254. $lastArr = [];
  1255. switch ($type) {
  1256. case 'yesterday' :
  1257. $timeArr = Time::yesterday();
  1258. $lastArr = Time::yesterday(1);
  1259. break;
  1260. case 'week' :
  1261. $timeArr = Time::week();
  1262. $lastArr = Time::lastWeek();
  1263. break;
  1264. case 'lastWeek' :
  1265. $timeArr = Time::lastWeek();
  1266. break;
  1267. case 'month' :
  1268. $timeArr = Time::month();
  1269. $lastArr = Time::lastMonth();
  1270. break;
  1271. case 'lastMonth' :
  1272. $timeArr = Time::lastMonth();
  1273. $lastArr = Time::lastMonth(1);
  1274. break;
  1275. case 'quarter' :
  1276. //本季度
  1277. $month = date('m');
  1278. if ($month == 1 || $month == 2 || $month == 3) {
  1279. $daterange_start_time = strtotime(date('Y-01-01 00:00:00'));
  1280. $daterange_end_time = strtotime(date("Y-03-31 23:59:59"));
  1281. } elseif ($month == 4 || $month == 5 || $month == 6) {
  1282. $daterange_start_time = strtotime(date('Y-04-01 00:00:00'));
  1283. $daterange_end_time = strtotime(date("Y-06-30 23:59:59"));
  1284. } elseif ($month == 7 || $month == 8 || $month == 9) {
  1285. $daterange_start_time = strtotime(date('Y-07-01 00:00:00'));
  1286. $daterange_end_time = strtotime(date("Y-09-30 23:59:59"));
  1287. } else {
  1288. $daterange_start_time = strtotime(date('Y-10-01 00:00:00'));
  1289. $daterange_end_time = strtotime(date("Y-12-31 23:59:59"));
  1290. }
  1291. //上季度
  1292. $month = date('m');
  1293. if ($month == 1 || $month == 2 || $month == 3) {
  1294. $year = date('Y') - 1;
  1295. $daterange_start_time_last_time = strtotime(date($year . '-10-01 00:00:00'));
  1296. $daterange_end_time_last_time = strtotime(date($year . '-12-31 23:59:59'));
  1297. } elseif ($month == 4 || $month == 5 || $month == 6) {
  1298. $daterange_start_time_last_time = strtotime(date('Y-01-01 00:00:00'));
  1299. $daterange_end_time_last_time = strtotime(date("Y-03-31 23:59:59"));
  1300. } elseif ($month == 7 || $month == 8 || $month == 9) {
  1301. $daterange_start_time_last_time = strtotime(date('Y-04-01 00:00:00'));
  1302. $daterange_end_time_last_time = strtotime(date("Y-06-30 23:59:59"));
  1303. } else {
  1304. $daterange_start_time_last_time = strtotime(date('Y-07-01 00:00:00'));
  1305. $daterange_end_time_last_time = strtotime(date("Y-09-30 23:59:59"));
  1306. }
  1307. $timeArr = array($daterange_start_time, $daterange_end_time);
  1308. $lastArr = array($daterange_start_time_last_time, $daterange_end_time_last_time);
  1309. break;
  1310. case 'lastQuarter' :
  1311. //上季度
  1312. $month = date('m');
  1313. if ($month == 1 || $month == 2 || $month == 3) {
  1314. $year = date('Y') - 1;
  1315. $daterange_start_time = strtotime(date($year . '-10-01 00:00:00'));
  1316. $daterange_end_time = strtotime(date($year . '-12-31 23:59:59'));
  1317. } elseif ($month == 4 || $month == 5 || $month == 6) {
  1318. $daterange_start_time = strtotime(date('Y-01-01 00:00:00'));
  1319. $daterange_end_time = strtotime(date("Y-03-31 23:59:59"));
  1320. } elseif ($month == 7 || $month == 8 || $month == 9) {
  1321. $daterange_start_time = strtotime(date('Y-04-01 00:00:00'));
  1322. $daterange_end_time = strtotime(date("Y-06-30 23:59:59"));
  1323. } else {
  1324. $daterange_start_time = strtotime(date('Y-07-01 00:00:00'));
  1325. $daterange_end_time = strtotime(date("Y-09-30 23:59:59"));
  1326. }
  1327. $timeArr = array($daterange_start_time, $daterange_end_time);
  1328. $lastArr = array($daterange_start_time_last_time, $daterange_end_time_last_time);
  1329. break;
  1330. case 'year' :
  1331. $timeArr = Time::year();
  1332. $lastArr = Time::lastYear();
  1333. break;
  1334. case 'lastYear' :
  1335. $timeArr = Time::lastYear();
  1336. $lastArr = Time::lastYear(1);
  1337. break;
  1338. default :
  1339. $timeArr = Time::today();
  1340. $lastArr = Time::yesterday();
  1341. break;
  1342. }
  1343. if ($is_last) {
  1344. return $lastArr;
  1345. } else {
  1346. return $timeArr;
  1347. }
  1348. }
  1349. /**
  1350. * 服务器附件完整路径处理
  1351. * @param
  1352. */
  1353. function getFullPath($path)
  1354. {
  1355. if ($path) {
  1356. $protocol = strpos(strtolower($_SERVER['server_protocol']), 'https') === false ? 'http' : 'https';
  1357. return $protocol . '://' . $_SERVER['HTTP_HOST'] . substr($_SERVER["SCRIPT_NAME"], 0, -10) . substr(str_replace(DS, '/', $path), 1);
  1358. } else {
  1359. return '';
  1360. }
  1361. }
  1362. /*取得文件后缀*/
  1363. function getExtension($filename)
  1364. {
  1365. $mytext = substr($filename, strrpos($filename, '.') + 1);
  1366. return $mytext;
  1367. }
  1368. /**
  1369. * 生成编号
  1370. * @param prefix 前缀
  1371. * @return
  1372. * @author Michael_xu
  1373. */
  1374. function prefixNumber($prefix, $number_id = 0, $str = 5)
  1375. {
  1376. return $prefixNumber = $prefix . str_pad($number_id, $str, 0, STR_PAD_LEFT); //填充字符串的左侧(将字符串填充为新的长度)
  1377. }
  1378. /**
  1379. * curl 模拟GET请求
  1380. * @author lee
  1381. ***/
  1382. function curl_get($url)
  1383. {
  1384. //初始化
  1385. $ch = curl_init();
  1386. //设置抓取的url
  1387. curl_setopt($ch, CURLOPT_URL, $url);
  1388. //设置获取的信息以文件流的形式返回,而不是直接输出。
  1389. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  1390. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书
  1391. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // https请求 不验证hosts
  1392. //执行命令
  1393. $output = curl_exec($ch);
  1394. curl_close($ch); //释放curl句柄
  1395. return $output;
  1396. }
  1397. /**
  1398. * 地址坐标转换
  1399. * @param prefix 前缀
  1400. * @return
  1401. * @author Michael_xu
  1402. */
  1403. function get_lng_lat($address)
  1404. {
  1405. $map_ak = config('map_ak');
  1406. $url = "http://api.map.baidu.com/geocoder/v2/?address=$address&output=json&ak=$map_ak&callback=showLocation";
  1407. $ret_script = curl_get($url);
  1408. preg_match_all("/\{.*?\}}/is", $ret_script, $matches);
  1409. $ret_arr = json_decode($matches[0][0], true);
  1410. if ($ret_arr['status'] == 0) { //成功
  1411. $location['lng'] = $ret_arr['result']['location']['lng'];
  1412. $location['lat'] = $ret_arr['result']['location']['lat'];
  1413. return $location;
  1414. } else {
  1415. return false;
  1416. }
  1417. }
  1418. /**
  1419. * 导出数据为excel表格
  1420. * @param $data 一个二维数组,结构如同从数据库查出来的数组
  1421. * @param $title excel的第一行标题,一个数组,如果为空则没有标题
  1422. * @param $filename 下载的文件名
  1423. * @param exportexcel($arr,array('id','账户','密码','昵称'),'文件名!');
  1424. */
  1425. function exportexcel($data = array(), $title = array(), $filename = 'report')
  1426. {
  1427. header("Content-type:application/octet-stream");
  1428. header("Accept-Ranges:bytes");
  1429. header("Content-type:application/vnd.ms-excel");
  1430. header("Content-Disposition:attachment;filename=" . $filename . ".xls");
  1431. header("Pragma: no-cache");
  1432. header("Expires: 0");
  1433. //导出xls 开始
  1434. if (!empty($title)) {
  1435. foreach ($title as $k => $v) {
  1436. $title[$k] = iconv("UTF-8", "GB2312", $v);
  1437. }
  1438. $title = implode("\t", $title);
  1439. echo "$title\n";
  1440. }
  1441. if (!empty($data)) {
  1442. foreach ($data as $key => $val) {
  1443. foreach ($val as $ck => $cv) {
  1444. $data[$key][$ck] = iconv("UTF-8", "GB2312", $cv);
  1445. }
  1446. $data[$key] = implode("\t", $data[$key]);
  1447. }
  1448. echo implode("\n", $data);
  1449. }
  1450. }
  1451. //根据数据库查询出来数组获取某个字段拼接字符串
  1452. function getFieldArray($array = array(), $field = '')
  1453. {
  1454. if (is_array($array) && $field) {
  1455. $ary = array();
  1456. foreach ($array as $value) {
  1457. $ary[] = $value[$field];
  1458. }
  1459. $str = implode(',', $ary);
  1460. return $str;
  1461. } else {
  1462. return false;
  1463. }
  1464. }
  1465. /**
  1466. * 检查该字段若必填,加上"*"
  1467. * @param is_null 是否为空 0否 1是
  1468. * @param name 字段名称
  1469. **/
  1470. function sign_required($is_null, $name)
  1471. {
  1472. if ($is_null == 1) {
  1473. return '*' . $name;
  1474. } else {
  1475. return $name;
  1476. }
  1477. }
  1478. /**
  1479. * [获取是否有管理员角色 adminGroupTypes]
  1480. * @param user_id 当前人ID
  1481. * @return
  1482. */
  1483. function adminGroupTypes($user_id)
  1484. {
  1485. $userModel = new UserModel();
  1486. $groupsArr = $userModel->get($user_id)->groups;
  1487. $groupids = [];
  1488. if ($groupsArr) {
  1489. foreach ($groupsArr as $key => $val) {
  1490. $groupids[] = $val['id'];
  1491. }
  1492. }
  1493. $types = db('admin_group')->where(['id' => ['in', $groupids]])->group('types')->column('types');
  1494. if ($user_id == 1) {
  1495. $types[] = 1;
  1496. }
  1497. return $types ?: [];
  1498. }
  1499. /**
  1500. * [权限数组]
  1501. * @param ruleIds 当前人权限id
  1502. * @return
  1503. */
  1504. function rulesListToArray($rulesList, $ruleIds = [])
  1505. {
  1506. $newList = [];
  1507. if (!is_array($rulesList)) {
  1508. return array();
  1509. } else {
  1510. foreach ($rulesList as $k => $v) {
  1511. if (!is_array($v['children'])) continue;
  1512. foreach ($v['children'] as $k1 => $v1) {
  1513. if (!is_array($v1['children'])) continue;
  1514. foreach ($v1['children'] as $k2 => $v2) {
  1515. $check = false;
  1516. if (in_array($v2['id'], $ruleIds)) {
  1517. $check = true;
  1518. }
  1519. $newList[$v['name']][$v1['name']][$v2['name']] = $check;
  1520. }
  1521. }
  1522. }
  1523. }
  1524. return $newList ?: [];
  1525. }
  1526. /**
  1527. * [获取下一审批信息 nextCheckData]
  1528. * @param user_id 审批申请人ID
  1529. * @param flow_id 审批流ID
  1530. * @param types 关联对象
  1531. * @param types_id 联对象ID
  1532. * @param order_id 审批排序ID
  1533. * @return
  1534. */
  1535. function nextCheckData($user_id, $flow_id, $types, $types_id, $order_id, $check_user_id)
  1536. {
  1537. $new_order_id = $order_id;
  1538. $max_order_id = db('admin_examine_step')->where(['flow_id' => $flow_id])->max('order_id'); //审批流最大排序ID
  1539. $examineStepModel = new \app\admin\model\ExamineStep();
  1540. $stepInfo = $examineStepModel->getStepByOrder($flow_id, $new_order_id); //审批步骤
  1541. $next_user_ids = [];
  1542. $is_end = 0; //审批结束
  1543. //固定流程(status 1负责人主管,2指定用户(任意一人),3指定用户(多人会签),4上一级审批人主管)
  1544. //当前步骤审批人user_id
  1545. $step_user_ids = $examineStepModel->getUserByStep($stepInfo['step_id'], $user_id);
  1546. if ($step_user_ids) {
  1547. if (!$order_id) {
  1548. //创建时使用
  1549. $sub_user_ids = stringToArray($step_user_ids);
  1550. } else {
  1551. if ($stepInfo['status'] == 3) {
  1552. //会签(并关系)
  1553. //当前步骤已审批user_id
  1554. $check_user_ids = $examineStepModel->getUserByCheck($types, $types_id, $new_order_id);
  1555. $user_ids[] = $check_user_id;
  1556. $check_user_ids = $check_user_ids ? array_merge($check_user_ids, $user_ids) : $user_ids;
  1557. //剩余审批人user_id
  1558. $sub_user_ids = $check_user_ids ? array_diff(explode(',', $step_user_ids), $check_user_ids) : $step_user_ids;
  1559. $sub_user_ids = array_unique(array_filter($sub_user_ids));
  1560. if (!$sub_user_ids) {
  1561. $is_end = 1;
  1562. }
  1563. } else {
  1564. $is_end = 1;
  1565. }
  1566. }
  1567. } else {
  1568. $is_end = 1;
  1569. }
  1570. if ($is_end == 1) {
  1571. $next_order_id = $new_order_id + 1;
  1572. } else {
  1573. $next_order_id = $new_order_id;
  1574. }
  1575. //当前审批步骤已结束
  1576. if ($is_end == 1) {
  1577. //当前审批流程是否结束
  1578. $stepInfo = $examineStepModel->getStepByOrder($flow_id, $next_order_id); //审批步骤
  1579. $next_step_user_ids = $examineStepModel->getUserByStep($stepInfo['step_id'], $user_id);
  1580. $next_user_ids = stringToArray($next_step_user_ids);
  1581. } else {
  1582. $next_user_ids = array_unique(array_filter($sub_user_ids));
  1583. }
  1584. if (!$next_user_ids && $next_order_id <= $max_order_id) {
  1585. $newRes = [];
  1586. $newRes = nextCheckData($user_id, $flow_id, $types, $types_id, $next_order_id, $check_user_id);
  1587. $next_user_ids = $newRes['next_user_ids'];
  1588. }
  1589. $data = [];
  1590. $data['order_id'] = ($next_order_id <= $max_order_id) ? $next_order_id : $max_order_id;
  1591. $data['next_user_ids'] = $next_user_ids ?: '';
  1592. return $data;
  1593. }
  1594. /**
  1595. * 解析获取php.ini 的upload_max_filesize(单位:byte)
  1596. * @param $dec int 小数位数
  1597. * @return float (单位:byte)
  1598. * */
  1599. function get_upload_max_filesize_byte($dec = 2)
  1600. {
  1601. $max_size = ini_get('upload_max_filesize');
  1602. preg_match('/(^[0-9\.]+)(\w+)/', $max_size, $info);
  1603. $size = $info[1];
  1604. $suffix = strtoupper($info[2]);
  1605. $a = array_flip(array("B", "KB", "MB", "GB", "TB", "PB"));
  1606. $b = array_flip(array("B", "K", "M", "G", "T", "P"));
  1607. $pos = $a[$suffix] && $a[$suffix] !== 0 ? $a[$suffix] : $b[$suffix];
  1608. return round($size * pow(1024, $pos), $dec);
  1609. }
  1610. /**
  1611. * 模拟post进行url请求
  1612. * @param string $url
  1613. * @param string $param
  1614. */
  1615. function curl_post($url = '', $post = array())
  1616. {
  1617. $curl = curl_init(); // 启动一个CURL会话
  1618. curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
  1619. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
  1620. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
  1621. curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
  1622. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
  1623. curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
  1624. curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
  1625. curl_setopt($curl, CURLOPT_POSTFIELDS, $post); // Post提交的数据包
  1626. curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
  1627. curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
  1628. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
  1629. $res = curl_exec($curl); // 执行操作
  1630. if (curl_errno($curl)) {
  1631. echo 'Errno' . curl_error($curl);//捕抓异常
  1632. }
  1633. curl_close($curl); // 关闭CURL会话
  1634. return $res; // 返回数据,json格式
  1635. }
  1636. /**
  1637. * 输出json字符串,用于接口调试
  1638. *
  1639. * @return void
  1640. * @author ymob
  1641. */
  1642. function vdd()
  1643. {
  1644. header('Content-Type: text/json; charset=utf-8');
  1645. $args = func_get_args();
  1646. foreach ($args as &$val) {
  1647. if ($val instanceof think\Model) {
  1648. $val = $val->getLastSql();
  1649. }
  1650. }
  1651. if (count($args) < 2) {
  1652. $args = array_shift($args);
  1653. }
  1654. die(json_encode($args));
  1655. }
  1656. /**
  1657. * 根据时间查询参数返回时间条件 (用于统计分析模块)
  1658. *
  1659. * @param array $where
  1660. * @param string $field
  1661. * @return void
  1662. * @author ymob
  1663. */
  1664. function getWhereTimeByParam(&$where, $field = 'create_time')
  1665. {
  1666. $param = request()->param();
  1667. if (empty($param['type']) && empty($param['start_time'])) {
  1668. $param['type'] = 'month';
  1669. }
  1670. if (!empty($param['start_time'])) {
  1671. $where[$field] = ['between', [$param['start_time'], $param['end_time']]];
  1672. } else {
  1673. $timeRange = getTimeByType($param['type']);
  1674. if ($timeRange) {
  1675. $where[$field] = ['between', [$timeRange[0], $timeRange[1]]];
  1676. }
  1677. }
  1678. }
  1679. /**
  1680. * 根据员工、部门查询参数返回员工、部门条件 (用于统计分析模块)
  1681. *
  1682. * @param array $where
  1683. * @param string $field
  1684. * @param string $m
  1685. * @param string $c
  1686. * @param string $a
  1687. * @return void
  1688. * @author ymob
  1689. */
  1690. function getWhereUserByParam(&$where, $field = 'owner_user_id', $m = '', $c = '', $a = '')
  1691. {
  1692. $param = request()->param();
  1693. $userModel = new UserModel();
  1694. $map_user_ids = [];
  1695. if ($param['user_id']) {
  1696. $map_user_ids = array($param['user_id']);
  1697. } elseif ($param['structure_id']) {
  1698. $map_user_ids = $userModel->getSubUserByStr($param['structure_id'], 2);
  1699. } else {
  1700. $map_user_ids = $userModel->getUserByPer($m, $c, $a);
  1701. $where[$field] = array('in', $map_user_ids);
  1702. return;
  1703. }
  1704. $perUserIds = $userModel->getUserByPer($m, $c, $a); //权限范围内userIds
  1705. $userIds = array_intersect($map_user_ids, $perUserIds); //数组交集
  1706. $where[$field] = array('in', $userIds);
  1707. }
  1708. /**
  1709. * 获取客户浏览器类型
  1710. */
  1711. function getBrowser()
  1712. {
  1713. $Browser = $_SERVER['HTTP_USER_AGENT'];
  1714. if (preg_match('/MSIE/i', $Browser)) {
  1715. $Browser = 'MSIE';
  1716. } elseif (preg_match('/Firefox/i', $Browser)) {
  1717. $Browser = 'Firefox';
  1718. } elseif (preg_match('/Chrome/i', $Browser)) {
  1719. $Browser = 'Chrome';
  1720. } elseif (preg_match('/Safari/i', $Browser)) {
  1721. $Browser = 'Safari';
  1722. } elseif (preg_match('/Opera/i', $Browser)) {
  1723. $Browser = 'Opera';
  1724. } else {
  1725. $Browser = 'Other';
  1726. }
  1727. return $Browser;
  1728. }
  1729. /**
  1730. * 获取客户端系统
  1731. */
  1732. function getOS()
  1733. {
  1734. $agent = $_SERVER['HTTP_USER_AGENT'];
  1735. if (preg_match('/win/i', $agent)) {
  1736. if (preg_match('/nt 6.1/i', $agent)) {
  1737. $OS = 'Windows 7';
  1738. } else if (preg_match('/nt 6.2/i', $agent)) {
  1739. $OS = 'Windows 8';
  1740. } else if (preg_match('/nt 10.0/i', $agent)) {
  1741. $OS = 'Windows 10';
  1742. } else {
  1743. $OS = 'Windows';
  1744. }
  1745. } elseif (preg_match('/mac/i', $agent)) {
  1746. $OS = 'MAC';
  1747. } elseif (preg_match('/linux/i', $agent)) {
  1748. $OS = 'Linux';
  1749. } elseif (preg_match('/unix/i', $agent)) {
  1750. $OS = 'Unix';
  1751. } elseif (preg_match('/bsd/i', $agent)) {
  1752. $OS = 'BSD';
  1753. } else {
  1754. $OS = 'Other';
  1755. }
  1756. return $OS;
  1757. }
  1758. /**
  1759. * 根据IP获取地址
  1760. */
  1761. function getAddress($ip)
  1762. {
  1763. $res = file_get_contents("http://ip.360.cn/IPQuery/ipquery?ip=" . $ip);
  1764. $res = json_decode($res, 1);
  1765. if ($res && $res['errno'] == 0) {
  1766. return explode("\t", $res['data'])[0];
  1767. } else {
  1768. return '';
  1769. }
  1770. }
  1771. /**
  1772. * 下载服务器文件
  1773. *
  1774. * @param string $file 文件路径
  1775. * @param string $name 下载名称
  1776. * @param boolean $del 下载后删除
  1777. * @return void
  1778. * @author Ymob
  1779. */
  1780. function download($file, $name = '', $del = false)
  1781. {
  1782. if (!file_exists($file)) {
  1783. return resultArray([
  1784. 'error' => '文件不存在',
  1785. ]);
  1786. }
  1787. // 仅允许下载 public 目录下文件
  1788. $res = strpos(realpath($file), realpath('./public'));
  1789. if ($res !== 0) {
  1790. return resultArray([
  1791. 'error' => '文件路径错误',
  1792. ]);
  1793. }
  1794. $fp = fopen($file, 'r');
  1795. $size = filesize($file);
  1796. //下载文件需要的头
  1797. header("Content-type: application/octet-stream");
  1798. header("Accept-Ranges: bytes");
  1799. header('ResponseType: blob');
  1800. header("Accept-Length: $size");
  1801. $file_name = $name != '' ? $name : pathinfo($file, PATHINFO_BASENAME);
  1802. // urlencode 处理中文乱码
  1803. header("Content-Disposition:attachment; filename=" . urlencode($file_name));
  1804. // 导出数据时 csv office Excel 需要添加bom头
  1805. if (pathinfo($file, PATHINFO_EXTENSION) == 'csv') {
  1806. echo "\xEF\xBB\xBF"; // UTF-8 BOM
  1807. }
  1808. $fileCount = 0;
  1809. $fileUnit = 1024;
  1810. while (!feof($fp) && $size - $fileCount > 0) {
  1811. $fileContent = fread($fp, $fileUnit);
  1812. echo $fileContent;
  1813. $fileCount += $fileUnit;
  1814. }
  1815. fclose($fp);
  1816. // 删除
  1817. if ($del) @unlink($file);
  1818. die();
  1819. }
  1820. /**
  1821. * 临时目录生成文件名,并返回绝对路径
  1822. *
  1823. * @param string $ext 文件类型后缀
  1824. * @param string $path 临时文件目录 默认 ./public/temp/
  1825. * @return string $file_path 文件名称绝对路径
  1826. * @author ymob
  1827. */
  1828. function tempFileName($ext = '')
  1829. {
  1830. // 临时目录
  1831. $path = TEMP_DIR . date('Ymd') . DS;
  1832. if (!file_exists($path)) {
  1833. mkdir($path, 0777, true);
  1834. }
  1835. $ext = trim($ext, '.');
  1836. do {
  1837. $temp_file = md5(time() . rand(1000, 9999));
  1838. $file_path = $path . $temp_file . '.' . $ext;
  1839. } while (file_exists($file_path));
  1840. return $file_path;
  1841. }
  1842. /**
  1843. * 递归删除目录
  1844. *
  1845. * @param string $dir
  1846. * @return void
  1847. * @author Ymob
  1848. */
  1849. function delDir($dir)
  1850. {
  1851. $dh = opendir($dir);
  1852. while ($file = readdir($dh)) {
  1853. if ($file != "." && $file != "..") {
  1854. $fullpath = $dir . "/" . $file;
  1855. if (!is_dir($fullpath)) {
  1856. @unlink($fullpath);
  1857. } else {
  1858. deldir($fullpath);
  1859. }
  1860. }
  1861. }
  1862. closedir($dh);
  1863. //删除当前文件夹:
  1864. @rmdir($dir);
  1865. }
  1866. /**
  1867. * 商业智能 查询缓存
  1868. *
  1869. * @param string $sql Sql语句
  1870. * @param int $bi_slow_query_time 慢查询时间(毫秒),默认读取Config(bi_slow_query_time)
  1871. * @return mixed
  1872. * @author Ymob
  1873. * @datetime 2019-11-21 17:36:50
  1874. */
  1875. function queryCache($sql = '', $bi_slow_query_time = null)
  1876. {
  1877. $key = 'BI_queryCache' . md5($sql);
  1878. $val = cache($key);
  1879. if (!$val) {
  1880. $start_time = microtime(true) * 1000;
  1881. $val = Db::query($sql);
  1882. $end_time = microtime(true) * 1000;
  1883. $slow_query = true;
  1884. // 是否使用系统默认设置-慢查询时间
  1885. if ($bi_slow_query_time === null) {
  1886. $bi_slow_query_time = config('bi_slow_query_time');
  1887. }
  1888. if ($bi_slow_query_time > 0) {
  1889. $slow_query = ($end_time - $start_time) > $bi_slow_query_time;
  1890. }
  1891. if ($slow_query && $val) {
  1892. cache($key, $val, config('bi_cache_time'));
  1893. }
  1894. }
  1895. return $val;
  1896. }
  1897. /**
  1898. * 图表时间范围处理,按月/天返回时间段数组
  1899. *
  1900. * @param int $start 开始时间(时间戳)
  1901. * @param int $end 结束时间(时间戳)
  1902. * @return array
  1903. * @author Ymob
  1904. * @datetime 2019-11-18 09:25:09
  1905. */
  1906. function getTimeArray($start = null, $end = null)
  1907. {
  1908. if ($start == null || $end == null) {
  1909. $param = request()->param();
  1910. switch ($param['type']) {
  1911. // 本年
  1912. case 'year':
  1913. $start = strtotime(date('Y-01-01'));
  1914. $end = strtotime('+1 year', $start) - 1;
  1915. break;
  1916. // 去年
  1917. case 'lastYear':
  1918. $start = strtotime(date(date('Y') - 1 . '-01-01'));
  1919. $end = strtotime('+1 year', $start) - 1;
  1920. break;
  1921. // 本季度、上季度
  1922. case 'quarter':
  1923. case 'lastQuarter':
  1924. $t = intval((date('m') - 1) / 3);
  1925. $start_y = ($t * 3) + 1;
  1926. $start = strtotime(date("Y-{$start_y}-01"));
  1927. if ($param['type'] == 'lastQuarter') { // 上季度
  1928. $start = strtotime('-3 month', $start);
  1929. }
  1930. $end = strtotime('+3 month', $start) - 1;
  1931. break;
  1932. // 本月、上月
  1933. case 'month':
  1934. case 'lastMonth':
  1935. $start = strtotime(date('Y-m-01'));
  1936. if ($param['type'] == 'lastMonth') {
  1937. $start = strtotime('-1 month', $start);
  1938. }
  1939. $end = strtotime('+1 month', $start) - 1;
  1940. break;
  1941. // 本周、上周
  1942. case 'week':
  1943. case 'lastWeek':
  1944. $start = strtotime('-' . (date('w') - 1) . 'day', strtotime(date('Y-m-d')));
  1945. if ($param['type'] == 'lastWeek') {
  1946. $start = strtotime('-7 day', $start);
  1947. }
  1948. $end = strtotime('+7 day', $start) - 1;
  1949. break;
  1950. // 今天、昨天
  1951. case 'today':
  1952. case 'yesterday':
  1953. $start = strtotime(date('Y-m-d'));
  1954. if ($param['type'] == 'yesterday') {
  1955. $start = strtotime('-1 day', $start);
  1956. }
  1957. $end = strtotime('+1 day', $start) - 1;
  1958. break;
  1959. default:
  1960. if ($param['start_time'] && $param['end_time']) {
  1961. $start = $param['start_time'];
  1962. $end = $param['end_time'];
  1963. } else {
  1964. // 本年
  1965. $start = strtotime(date('Y-01-01'));
  1966. $end = strtotime('+1 year', $start) - 1;
  1967. }
  1968. break;
  1969. }
  1970. }
  1971. $between = [$start, $end];
  1972. $list = [];
  1973. $len = ($end - $start) / 86400;
  1974. // 大于30天 按月统计、小于按天统计
  1975. if ($len > 31) {
  1976. $time_format = '%Y-%m';
  1977. while (true) {
  1978. $start = strtotime(date('Y-m-01', $start));
  1979. $item = [];
  1980. $item['type'] = date('Y-m', $start);
  1981. $item['start_time'] = $start;
  1982. $item['end_time'] = strtotime('+1 month', $start) - 1;
  1983. $list[] = $item;
  1984. if ($item['end_time'] >= $end) break;
  1985. $start = $item['end_time'] + 1;
  1986. }
  1987. } else {
  1988. $time_format = '%Y-%m-%d';
  1989. while (true) {
  1990. $item = [];
  1991. $item['type'] = date('Y-m-d', $start);
  1992. $item['start_time'] = $start;
  1993. $item['end_time'] = strtotime('+1 day', $start) - 1;
  1994. $list[] = $item;
  1995. if ($item['end_time'] >= $end) break;
  1996. $start = $item['end_time'] + 1;
  1997. }
  1998. }
  1999. return [
  2000. 'list' => $list, // 时间段列表
  2001. 'time_format' => $time_format, // 时间格式 mysql 格式化时间戳
  2002. 'between' => $between // 开始结束时间
  2003. ];
  2004. }
  2005. /**
  2006. * 打印程序执行时间
  2007. *
  2008. * @param integer $s
  2009. * @return void
  2010. * @author Ymob
  2011. * @datetime 2019-11-28 09:31:45
  2012. */
  2013. function tt($s = 0)
  2014. {
  2015. die((string)round(microtime(1) - ($s ?: THINK_START_TIME), 3));
  2016. }
  2017. /**
  2018. * 数据库备份
  2019. */
  2020. function DBBackup($file = '', $path = '')
  2021. {
  2022. $type = config('database.type');
  2023. $host = config('database.hostname');
  2024. $port = config('database.hostport');
  2025. $dbname = config('database.database');
  2026. $username = config('database.username');
  2027. $password = config('database.password');
  2028. $dsn = "{$type}:host={$host};dbname={$dbname};port={$port}";
  2029. if ($file == '') {
  2030. $save_path = dirname(APP_PATH) . DS . 'data' . DS . date('Ym') . DS;
  2031. if (!file_exists($save_path) && !mkdir($save_path, '0777', true)) {
  2032. return 'data目录无写入权限';
  2033. }
  2034. $file = $save_path . date('d_H_i') . '_db_backup' . '.sql';
  2035. }
  2036. if (file_exists($file)) {
  2037. return '数据库备份文件已存在(自动备份时间间隔需大于1分钟)。';
  2038. }
  2039. try {
  2040. $backup = new \com\Mysqldump($dsn, $username, $password);
  2041. $backup->start($file);
  2042. return true;
  2043. } catch (\Exception $e) {
  2044. return '备份失败,请手动备份。错误原因:' . $e->getMessage();
  2045. }
  2046. }
  2047. /**
  2048. * 根据ip获取地址
  2049. */
  2050. function getAddressById($data)
  2051. {
  2052. $ip = new IpLocation();
  2053. $ip_address = $ip->getlocation($data);
  2054. return $ip_address;
  2055. }
  2056. if (!function_exists('isSuperAdministrators')) {
  2057. /**
  2058. * 判断是否是超级管理员
  2059. *
  2060. * @param $userId
  2061. * @return bool
  2062. */
  2063. function isSuperAdministrators($userId)
  2064. {
  2065. $status = false;
  2066. $apiCommon = new \app\admin\controller\ApiCommon();
  2067. $userId = !empty($userId) ? $userId : $apiCommon->userInfo['id'];
  2068. $data = db('admin_access')->where('user_id', $userId)->column('group_id');
  2069. if ($userId == 1 || in_array(1, $data)) {
  2070. $status = true;
  2071. }
  2072. return $status;
  2073. }
  2074. }
  2075. if (!function_exists('getFieldGrantData')) {
  2076. /**
  2077. * 获取自动授权数据
  2078. *
  2079. * @return array
  2080. */
  2081. function getFieldGrantData($userId)
  2082. {
  2083. $result = [];
  2084. $apiCommon = new \app\admin\controller\ApiCommon();
  2085. $userId = !empty($userId) ? $userId : $apiCommon->userInfo['id'];
  2086. $grantData = Db::query("
  2087. SELECT
  2088. `grant`.`module`, `grant`.`column`, `grant`.`content`
  2089. FROM
  2090. `5kcrm_admin_access` AS `access`
  2091. LEFT JOIN
  2092. `5kcrm_admin_group` AS `group` ON `access`.`group_id` = `group`.`id`
  2093. LEFT JOIN
  2094. `5kcrm_admin_field_grant` AS `grant` ON `group`.`id` = `grant`.`role_id`
  2095. WHERE
  2096. `access`.`user_id` =
  2097. " . $userId);
  2098. # 存在多角色多授权的情况
  2099. foreach ($grantData as $key => $value) {
  2100. if (empty($value['module']) || empty($value['column'])) continue;
  2101. $result[$value['module'] . '_' . $value['column']][] = !empty($value['content']) ? unserialize($value['content']) : [];
  2102. }
  2103. return $result;
  2104. }
  2105. }
  2106. if (!function_exists('getFieldGrantStatus')) {
  2107. /**
  2108. * 获取字段授权状态
  2109. *
  2110. * @param $field
  2111. * @param $grantData
  2112. * @return int[]
  2113. */
  2114. function getFieldGrantStatus($field, $grantData)
  2115. {
  2116. # 默认状态都是不能查看、不能编辑,通过配置来取最大权限。
  2117. $result = ['read' => 0, 'write' => 0];
  2118. foreach ($grantData as $key => $value) {
  2119. $fieldBool = false;
  2120. foreach ($value as $ke => $va) {
  2121. # 多个字段授权,只取最高的读权限
  2122. if ($va['field'] == $field && $result['read'] == 0) {
  2123. $result['read'] = $va['read'] > $result['read'] ? $va['read'] : $result['read'];
  2124. }
  2125. # 多个字段授权,只取最高的写权限
  2126. if ($va['field'] == $field && $result['write'] == 0) {
  2127. $result['write'] = $va['write'] > $result['write'] ? $va['write'] : $result['write'];
  2128. }
  2129. if ($va['field'] == $field) $fieldBool = true;
  2130. }
  2131. # 对于不在权限控制之内的字段,将状态都改为1。
  2132. if (!$fieldBool) {
  2133. $result['read'] = 1;
  2134. $result['write'] = 1;
  2135. }
  2136. }
  2137. return $result;
  2138. }
  2139. /**
  2140. * 仪表盘日志使用
  2141. * 根据类型获取开始结束时间戳数组
  2142. * @param
  2143. */
  2144. function ByDateTime($type = 'today')
  2145. {
  2146. switch ($type) {
  2147. case 'yesterday' :
  2148. $timeArr = DataTime::yesterday();
  2149. $timeArr['last_time'] = DataTime::yesterday(1);
  2150. break;
  2151. case 'week' :
  2152. $timeArr = DataTime::week();
  2153. $timeArr['last_time'] = DataTime::lastWeek(1);
  2154. break;
  2155. case 'lastWeek' :
  2156. $timeArr = DataTime::lastWeek();
  2157. $timeArr['last_time'] = DataTime::lastWeek(1);
  2158. break;
  2159. case 'month' :
  2160. $timeArr = DataTime::month();
  2161. $timeArr['last_time'] = DataTime::lastMonth(1);
  2162. break;
  2163. case 'lastMonth' :
  2164. $timeArr = DataTime::lastMonth();
  2165. $timeArr['last_time'] = DataTime::lastMonth(1);
  2166. break;
  2167. case 'quarter' :
  2168. //本季度
  2169. $month = date('m');
  2170. if ($month == 1 || $month == 2 || $month == 3) {
  2171. $daterange_start_time = strtotime(date('Y-01-01 00:00:00'));
  2172. $daterange_end_time = strtotime(date("Y-03-31 23:59:59"));
  2173. } elseif ($month == 4 || $month == 5 || $month == 6) {
  2174. $daterange_start_time = strtotime(date('Y-04-01 00:00:00'));
  2175. $daterange_end_time = strtotime(date("Y-06-30 23:59:59"));
  2176. } elseif ($month == 7 || $month == 8 || $month == 9) {
  2177. $daterange_start_time = strtotime(date('Y-07-01 00:00:00'));
  2178. $daterange_end_time = strtotime(date("Y-09-30 23:59:59"));
  2179. } else {
  2180. $daterange_start_time = strtotime(date('Y-10-01 00:00:00'));
  2181. $daterange_end_time = strtotime(date("Y-12-31 23:59:59"));
  2182. }
  2183. //上季度
  2184. $month = date('m');
  2185. if ($month == 1 || $month == 2 || $month == 3) {
  2186. $year = date('Y') - 1;
  2187. $daterange_start_time_last_time = strtotime(date($year . '-10-01 00:00:00'));
  2188. $daterange_end_time_last_time = strtotime(date($year . '-12-31 23:59:59'));
  2189. } elseif ($month == 4 || $month == 5 || $month == 6) {
  2190. $daterange_start_time_last_time = strtotime(date('Y-01-01 00:00:00'));
  2191. $daterange_end_time_last_time = strtotime(date("Y-03-31 23:59:59"));
  2192. } elseif ($month == 7 || $month == 8 || $month == 9) {
  2193. $daterange_start_time_last_time = strtotime(date('Y-04-01 00:00:00'));
  2194. $daterange_end_time_last_time = strtotime(date("Y-06-30 23:59:59"));
  2195. } else {
  2196. $daterange_start_time_last_time = strtotime(date('Y-07-01 00:00:00'));
  2197. $daterange_end_time_last_time = strtotime(date("Y-09-30 23:59:59"));
  2198. }
  2199. $timeArr['last_time'] = array($daterange_start_time_last_time, $daterange_end_time_last_time);
  2200. $timeArr = array($daterange_start_time, $daterange_end_time);
  2201. break;
  2202. case 'lastQuarter' :
  2203. //上季度
  2204. $month = date('m');
  2205. if ($month == 1 || $month == 2 || $month == 3) {
  2206. $year = date('Y') - 1;
  2207. $daterange_start_time = strtotime(date($year . '-10-01 00:00:00'));
  2208. $daterange_end_time = strtotime(date($year . '-12-31 23:59:59'));
  2209. } elseif ($month == 4 || $month == 5 || $month == 6) {
  2210. $daterange_start_time = strtotime(date('Y-01-01 00:00:00'));
  2211. $daterange_end_time = strtotime(date("Y-03-31 23:59:59"));
  2212. } elseif ($month == 7 || $month == 8 || $month == 9) {
  2213. $daterange_start_time = strtotime(date('Y-04-01 00:00:00'));
  2214. $daterange_end_time = strtotime(date("Y-06-30 23:59:59"));
  2215. } else {
  2216. $daterange_start_time = strtotime(date('Y-07-01 00:00:00'));
  2217. $daterange_end_time = strtotime(date("Y-09-30 23:59:59"));
  2218. }
  2219. //上季度
  2220. $month = date('m');
  2221. if ($month == 1 || $month == 2 || $month == 3) {
  2222. $year = date('Y') - 2;
  2223. $daterange_start_time_last_time = strtotime(date($year . '-10-01 00:00:00'));
  2224. $daterange_end_time_last_time = strtotime(date($year . '-12-31 23:59:59'));
  2225. } elseif ($month == 4 || $month == 5 || $month == 6) {
  2226. $daterange_start_time_last_time = strtotime(date('Y-01-01 00:00:00'));
  2227. $daterange_end_time_last_time = strtotime(date("Y-03-31 23:59:59"));
  2228. } elseif ($month == 7 || $month == 8 || $month == 9) {
  2229. $daterange_start_time_last_time = strtotime(date('Y-04-01 00:00:00'));
  2230. $daterange_end_time_last_time = strtotime(date("Y-06-30 23:59:59"));
  2231. } else {
  2232. $daterange_start_time_last_time = strtotime(date('Y-07-01 00:00:00'));
  2233. $daterange_end_time_last_time = strtotime(date("Y-09-30 23:59:59"));
  2234. }
  2235. $timeArr = array($daterange_start_time, $daterange_end_time);
  2236. $timeArr['last_time'] = array($daterange_start_time_last_time, $daterange_end_time_last_time);
  2237. break;
  2238. case 'year' :
  2239. $timeArr = DataTime::year();
  2240. $timeArr['last_time'] = DataTime::lastYear(1);
  2241. break;
  2242. case 'lastYear' :
  2243. $timeArr = DataTime::lastYear();
  2244. $timeArr['last_time'] = DataTime::lastYear(1);
  2245. break;
  2246. case 'recent60' :
  2247. $timeArr = DataTime::recent60();
  2248. break;
  2249. case 'recent30' :
  2250. $timeArr = DataTime::recent30();
  2251. break;
  2252. default :
  2253. $timeArr = DataTime::today();
  2254. $timeArr['last_time'] = DataTime::yesterday(1);
  2255. break;
  2256. }
  2257. return $timeArr;
  2258. }
  2259. /**
  2260. * 系统操作日志
  2261. * @param int $user_id 用户
  2262. * @param string $types 方法所属模块
  2263. * @param int $action_id 操作
  2264. * @param string $module_name 模块
  2265. * @param string $action_name 修改添加删除新建
  2266. * @param array $oldData 旧数据
  2267. * @param array $newData 新数据
  2268. * @param string $target_name 被操作对象
  2269. * @param string $content 添加时创建使用
  2270. * @author alvin guogaobo
  2271. * @version 1.0 版本号
  2272. * @since 2021/3/26 0026 15:10
  2273. */
  2274. function SystemActionLog($user_id, $types, $module_name, $action_id, $action_name, $target_name, $oldData = [], $newData = [], $content = '')
  2275. {
  2276. //action_name 修改添加删除新建 action_id 操作id client_ip ip create_time时间 content 操作记录 target_name 被操作对象 module_name 模块 系统管理 固定 user_id 用户
  2277. $data = [];
  2278. $data['user_id'] = $user_id;
  2279. $data['create_time'] = time();
  2280. $data['client_ip'] = request()->ip();
  2281. $data['action_id'] = $action_id;
  2282. $data['action_name'] = $action_name;
  2283. $data['target_name'] = $target_name;
  2284. $data['module_name'] = $module_name;
  2285. $data['controller_name'] = $types;
  2286. $data['content'] = $content;
  2287. db('admin_system_log')->insert($data);
  2288. }
  2289. /**
  2290. * 系统操作日志
  2291. * @param int $user_id 用户
  2292. * @param string $types 方法所属模块
  2293. * @param string $action_name 修改添加删除新建
  2294. * @param string $target_name 被操作对象
  2295. * @param array $oldData 旧数据
  2296. * @param array $newData 新数据
  2297. * @param string $content 添加时创建使用
  2298. * @author alvin guogaobo
  2299. * @version 1.0 版本号
  2300. * @since 2021/4/2 0026 15:10
  2301. */
  2302. function RecordActionLog($user_id, $types, $action_name, $target_name, $oldData = [], $newData = [], $content = '')
  2303. {
  2304. //action_name 修改 添加 删除 client_ip ip create_time时间 content 操作记录 target_name 被操作对象 module 模块 user_id 用户
  2305. if (is_array($oldData) && is_array($newData) && $user_id) {
  2306. $differentData = array_diff_assoc($newData, $oldData);
  2307. $fieldModel = new FieldModel();
  2308. $userModel = new UserModel();
  2309. $structureModel = new \app\admin\model\Structure();
  2310. $field_arr = $fieldModel->getField(['types' => $types, 'unFormType' => ['file', 'form']]); //获取字段属性
  2311. $newFieldArr = array();
  2312. foreach ($field_arr as $k => $v) {
  2313. $newFieldArr[$v['field']] = $v;
  2314. }
  2315. $unField = ['update_time', 'create_time']; //定义过滤字段
  2316. $message = [];
  2317. $un_form_type = ['file', 'form'];
  2318. foreach ($differentData as $k => $v) {
  2319. if ($newFieldArr[$k] && !in_array($newFieldArr[$k]['form_type'], $un_form_type)) {
  2320. $field_name = '';
  2321. $field_name = $newFieldArr[$k]['name'];
  2322. $new_value = $v ?: '空';
  2323. $old_value = $oldData[$k] ?: '空';
  2324. switch ($newFieldArr[$k]['form_type']) {
  2325. case 'datetime' :
  2326. $new_value = $v ? date('Y-m-d', $v) : '';
  2327. $old_value = date('Y-m-d', $oldData[$k]);
  2328. if (!empty($v) && !empty($oldData[$k]))
  2329. break;
  2330. case 'user' :
  2331. $new_value = $v ? implode(',', $userModel->getUserNameByArr(stringToArray($v))) : '';
  2332. $old_value = $v ? implode(',', $userModel->getUserNameByArr(stringToArray($oldData[$k]))) : '';
  2333. break;
  2334. case 'structure' :
  2335. $new_value = $v ? implode(',', $structureModel->getStructureNameByArr(stringToArray($v))) : '';
  2336. $old_value = $v ? implode(',', $structureModel->getStructureNameByArr(stringToArray($oldData[$k]))) : '';
  2337. break;
  2338. case 'business_status' :
  2339. $new_value = $v ? db('crm_business_status')->where(['status_id' => $v])->value('name') : '';
  2340. $old_value = $v ? db('crm_business_status')->where(['status_id' => $oldData[$k]])->value('name') : '';
  2341. break;
  2342. case 'business_type' :
  2343. $new_value = $v ? db('crm_business_type')->where(['type_id' => $v])->value('name') : '';
  2344. $old_value = $v ? db('crm_business_type')->where(['type_id' => $oldData[$k]])->value('name') : '';
  2345. break;
  2346. case 'customer' :
  2347. $new_value = $v ? db('crm_customer')->where(['customer_id' => $v])->value('name') : '';
  2348. $old_value = $v ? db('crm_customer')->where(['customer_id' => $oldData[$k]])->value('name') : '';
  2349. break;
  2350. case 'category' :
  2351. $new_value = $v ? db('crm_product_category')->where(['category_id' => $v])->value('name') : '';
  2352. $old_value = $v ? db('crm_product_category')->where(['category_id' => $oldData[$k]])->value('name') : '';
  2353. break;
  2354. case 'business' :
  2355. $new_value = $v ? db('crm_business')->where(['business_id' => $v])->value('name') : '';
  2356. $old_value = $v ? db('crm_business')->where(['business_id' => $oldData[$k]])->value('name') : '';
  2357. break;
  2358. case 'visit' :
  2359. $new_value = $v ? db('crm_visit')->where(['visit_id' => $v])->value('number') : '';
  2360. $old_value = $v ? db('crm_visit')->where(['visit_id' => $oldData[$k]])->value('number') : '';
  2361. break;
  2362. case 'single_user' :
  2363. $new_value = $v ? db('admin_user')->where(['id' => $v])->value('realname') : '';
  2364. $old_value = $v ? db('admin_user')->where(['id' => $oldData['owner_user_id']])->value('realname') : '';
  2365. break;
  2366. case 'floatnumber' :
  2367. $new_value = $v ? number_format($v, 2) : '';
  2368. break;
  2369. }
  2370. if ($newFieldArr[$k]['field'] == 'check_status') {
  2371. $statusArr = ['0' => '待审核', '1' => '审核中', '2' => '审核通过', '3' => '已拒绝', '4' => '已撤回', '5' => '未提交'];
  2372. $new_value = $statusArr[$v];
  2373. $old_value = $statusArr[$oldData[$k]];
  2374. }
  2375. if ($old_value != $new_value) {
  2376. $message[] = '将 ' . "'" . $field_name . "'" . ' 由 ' . $old_value . ' 修改为 ' . $new_value;
  2377. }
  2378. }
  2379. }
  2380. if ($message) {
  2381. $data = [];
  2382. $data['user_id'] = $user_id;
  2383. $data['create_time'] = time();
  2384. $data['client_ip'] = request()->ip();
  2385. $data['action_name'] = $action_name;
  2386. $data['action_id'] = 1;
  2387. $data['target_name'] = $target_name;
  2388. $data['module'] = $types; //子模块 客户线索
  2389. $data['content'] = implode(',', $message);
  2390. db('admin_operation_log')->insert($data);
  2391. }
  2392. } elseif ($content) {
  2393. $data = [];
  2394. $data['user_id'] = $user_id;
  2395. $data['create_time'] = time();
  2396. $data['client_ip'] = request()->ip();
  2397. $data['action_name'] = $action_name;
  2398. $data['target_name'] = $target_name;
  2399. $data['action_id'] = 1;
  2400. $data['module'] = $types; //子模块 客户线索
  2401. $data['content'] = $content;
  2402. db('admin_operation_log')->insert($data);
  2403. }
  2404. }
  2405. }