Browse Source

first commit

Your Name 10 months ago
commit
44fd6f8a91
100 changed files with 60127 additions and 0 deletions
  1. 30
    0
      .gitignore
  2. 21
    0
      .htaccess
  3. 1
    0
      .user.ini
  4. 28
    0
      _wildcard.gdzcfw.com-key.pem
  5. 26
    0
      _wildcard.gdzcfw.com.pem
  6. 1
    0
      application/.htaccess
  7. 179
    0
      application/admin/behavior/ActionBeginBehavior.php
  8. 149
    0
      application/admin/behavior/AppEndBehavior.php
  9. 285
    0
      application/admin/behavior/AuthRoleBehavior.php
  10. 71
    0
      application/admin/behavior/ModuleInitBehavior.php
  11. 239
    0
      application/admin/behavior/ViewFilterBehavior.php
  12. 1407
    0
      application/admin/common.php
  13. 449
    0
      application/admin/conf/auth_rule.php
  14. 3
    0
      application/admin/conf/constant.php
  15. 71
    0
      application/admin/conf/global.php
  16. 0
    0
      application/admin/conf/md5list2.txt
  17. 1268
    0
      application/admin/conf/menu.php
  18. 5
    0
      application/admin/conf/session_conf.php
  19. 100
    0
      application/admin/config.php
  20. 842
    0
      application/admin/controller/AdPosition.php
  21. 1547
    0
      application/admin/controller/Admin.php
  22. 324
    0
      application/admin/controller/Ajax.php
  23. 1908
    0
      application/admin/controller/Archives.php
  24. 44
    0
      application/admin/controller/ArchivesFlag.php
  25. 1649
    0
      application/admin/controller/Arctype.php
  26. 930
    0
      application/admin/controller/Article.php
  27. 593
    0
      application/admin/controller/Ask.php
  28. 343
    0
      application/admin/controller/AuthRole.php
  29. 288
    0
      application/admin/controller/Base.php
  30. 460
    0
      application/admin/controller/Canal.php
  31. 1163
    0
      application/admin/controller/Channeltype.php
  32. 1640
    0
      application/admin/controller/Citysite.php
  33. 399
    0
      application/admin/controller/Coupon.php
  34. 1085
    0
      application/admin/controller/Custom.php
  35. 540
    0
      application/admin/controller/Discount.php
  36. 26
    0
      application/admin/controller/DiyExtend.php
  37. 1026
    0
      application/admin/controller/Download.php
  38. 9
    0
      application/admin/controller/Encodes.php
  39. 1799
    0
      application/admin/controller/Field.php
  40. 266
    0
      application/admin/controller/Filemanager.php
  41. 239
    0
      application/admin/controller/Foreign.php
  42. 1434
    0
      application/admin/controller/Form.php
  43. 937
    0
      application/admin/controller/Guestbook.php
  44. 742
    0
      application/admin/controller/Images.php
  45. 1870
    0
      application/admin/controller/Index.php
  46. 1615
    0
      application/admin/controller/Language.php
  47. 247
    0
      application/admin/controller/Level.php
  48. 234
    0
      application/admin/controller/Links.php
  49. 299
    0
      application/admin/controller/LinksGroup.php
  50. 55
    0
      application/admin/controller/Map.php
  51. 875
    0
      application/admin/controller/Media.php
  52. 2684
    0
      application/admin/controller/Member.php
  53. 291
    0
      application/admin/controller/Memgift.php
  54. 369
    0
      application/admin/controller/Navigation.php
  55. 465
    0
      application/admin/controller/Notice.php
  56. 84
    0
      application/admin/controller/Notify.php
  57. 767
    0
      application/admin/controller/Order.php
  58. 484
    0
      application/admin/controller/Other.php
  59. 222
    0
      application/admin/controller/PayApi.php
  60. 1500
    0
      application/admin/controller/Product.php
  61. 1246
    0
      application/admin/controller/RecycleBin.php
  62. 40
    0
      application/admin/controller/Region.php
  63. 352
    0
      application/admin/controller/Search.php
  64. 1149
    0
      application/admin/controller/Security.php
  65. 589
    0
      application/admin/controller/Seo.php
  66. 565
    0
      application/admin/controller/Seom.php
  67. 737
    0
      application/admin/controller/Sharp.php
  68. 2147
    0
      application/admin/controller/Shop.php
  69. 469
    0
      application/admin/controller/ShopComment.php
  70. 1940
    0
      application/admin/controller/ShopProduct.php
  71. 376
    0
      application/admin/controller/ShopService.php
  72. 82
    0
      application/admin/controller/Sitemap.php
  73. 969
    0
      application/admin/controller/Special.php
  74. 293
    0
      application/admin/controller/Statistics.php
  75. 2125
    0
      application/admin/controller/System.php
  76. 653
    0
      application/admin/controller/Tags.php
  77. 556
    0
      application/admin/controller/Tools.php
  78. 1011
    0
      application/admin/controller/Ueditor.php
  79. 162
    0
      application/admin/controller/Uiset.php
  80. 329
    0
      application/admin/controller/Upgrade.php
  81. 630
    0
      application/admin/controller/Uploadify.php
  82. 792
    0
      application/admin/controller/Uploadimgnew.php
  83. 387
    0
      application/admin/controller/UsersNotice.php
  84. 114
    0
      application/admin/controller/UsersRelease.php
  85. 98
    0
      application/admin/controller/UsersScore.php
  86. 85
    0
      application/admin/controller/Vertify.php
  87. 10
    0
      application/admin/controller/Weapp.php
  88. 24
    0
      application/admin/html.php
  89. 4
    0
      application/admin/lang/en-us.php
  90. 4
    0
      application/admin/lang/zh-cn.php
  91. 1654
    0
      application/admin/logic/AjaxLogic.php
  92. 741
    0
      application/admin/logic/ArchivesLogic.php
  93. 530
    0
      application/admin/logic/AskLogic.php
  94. 63
    0
      application/admin/logic/DiyExtendLogic.php
  95. 1035
    0
      application/admin/logic/EyouCmsLogic.php
  96. 750
    0
      application/admin/logic/FieldLogic.php
  97. 417
    0
      application/admin/logic/FilemanagerLogic.php
  98. 225
    0
      application/admin/logic/ForeignLogic.php
  99. 147
    0
      application/admin/logic/FormLogic.php
  100. 0
    0
      application/admin/logic/MemberLogic.php

+ 30
- 0
.gitignore View File

@@ -0,0 +1,30 @@
1
+#官方自带
2
+/.idea
3
+/.vscode
4
+*.log
5
+.env
6
+/.well-known
7
+
8
+#自定义
9
+*.log
10
+*.zip
11
+*.sql
12
+*.rar
13
+*.7z
14
+*.tar.gz
15
+
16
+
17
+/uploads/*
18
+/data/runtime/*
19
+/data/schema/*
20
+/data/sqldata_QFgBF45EkxK5Kyjgdzns/*
21
+/data/session_30mQsrNE/*
22
+/application/config.php
23
+/application/database.php
24
+/sitemaps/*
25
+
26
+composer.lock
27
+robots.txt
28
+sitemap/sitemap.html
29
+sitemap/sitemap.txt
30
+sitemap/sitemap.xml

+ 21
- 0
.htaccess View File

@@ -0,0 +1,21 @@
1
+
2
+<IfModule mod_rewrite.c>
3
+    Options +FollowSymlinks -Multiviews
4
+    RewriteEngine On
5
+
6
+    #http?????https
7
+    #RewriteCond %{SERVER_PORT} !^443$
8
+    #RewriteRule ^(.*)$ https://www.xxxxx.com/$1 [L,R=301]
9
+
10
+    RewriteCond %{REQUEST_FILENAME} !-d
11
+    RewriteCond %{REQUEST_FILENAME} !-f
12
+    RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
13
+    #RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
14
+    #RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
15
+
16
+    #???????????????
17
+    RewriteCond % !^$
18
+    RewriteRule data/(.*).(php|php3|php4|php5|php6|php7|pht|phtml|asp|aspx|jsp|exe|js|sql|perl|cgi|asa)$ ?C [F]
19
+    RewriteRule template/(.*).(php|php3|php4|php5|php6|php7|pht|phtml|asp|aspx|jsp|exe|perl|cgi|asa)$ ?C [F]
20
+    RewriteRule uploads/(.*).(php|php3|php4|php5|php6|php7|pht|phtml|asp|aspx|jsp|exe|js|perl|cgi|asa)$ ?C [F] 
21
+</IfModule>

+ 1
- 0
.user.ini View File

@@ -0,0 +1 @@
1
+open_basedir=/www/wwwroot/zc.dev.gdzcfw.com/:/tmp/

+ 28
- 0
_wildcard.gdzcfw.com-key.pem View File

@@ -0,0 +1,28 @@
1
+-----BEGIN PRIVATE KEY-----
2
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5r0Auea0aWUS/
3
+paZaUP2so3zol9PoyTOcMvMDrgy7hkoV8ZlUn8pnmZzI177vGzCUX/VAM2p44py+
4
+PoYbtBYYOBUH/cwcw53tvnDn4QDJsDsfYFJ+QVY4jbLrl8aQOFjtG4i0NCw5VMKu
5
+eyX/bu72cz9pjN8zzX/ekt+qyJgAH/3P2VOaWtCe2LVpxtqJSdqYdy4nrDGeHE6r
6
+HwQ/0Xg2TV9svlJ/Q+59AQxVFkRxiARmG8KXlzkEkHWxBWtPWGRxIaCSv0zFA1ZG
7
+7kctiUOmlPtLIe85zEWcicaKFRMvymCVCktu1YQr12vUhSSxka5luZSdQPCUMHm6
8
+zXEr3NI3AgMBAAECggEACIZ8WuXpRblth6MSZTksvH1xIbi+2QRL41MPh065dO6w
9
+fhtun80KXQFXin0lXhMQgu948i6qJ8y3x6BVRfZZwVjp1kkX0wZEPQMuaecRwzDd
10
+Ng6VGwji7YvL+DcqvbpoktJdz3BJy4QRwDMVRooQXK5j7fOy180Knux9anj1SaQa
11
+QYl3HiyhfbzS05ctDa0J7bqBH66cQMESOnqLI4BnqJERJ8luoUo/VHp6clpfWkrd
12
+Y+kITDU6gb/mJFUVH2yFkTFYqu89z6njci6y5GutUvZirP2ZrDqWr0fZepqQfgnR
13
+9mCpzBIP0qcwFNRO5G+mVNs/0oWufJxE6gKFvrMQSQKBgQDxvCSC2K/FOHiXhJND
14
+rKdZRJySQTycgXJbrpwsyujrEt/djJz8UMBPWQPTE0UvmPFhvU4R2aS8zWhiVAIS
15
+e3C5cAwBJ9tXHn0Sb2cewMVp7OfgxIq77s1z4DvG+N+7WXxI/lBJVQA7HBqivN5W
16
+xEPAmcgQpVP2hyjKCyjTSfVk+wKBgQDEpFzfwsuobDgVAxBP61hvkOc2jmcUhydw
17
+2uy2Gis9KtpYijyGsylNEERwvgvPc2l8ZLR9VZjAiPeXIS8fnLgx9l86JpSadHBj
18
+/tJcT/XQJGOKtjX8F4A6/QDwISgl2FIBc58GCYKZOrNzE7Rwycfdlrhezwuap0wh
19
+KBOUVbYq9QKBgAQr9glYCfiCV/ptbEkvspekynrvq0ccKMgSRFm1ir17zuc45QCp
20
+uBfmdl1vKLOAlTHVnYJLWj9z4AhKYNrGzJQ2rc5bTLq9KPVnfMUYGJASaZIEckx5
21
++4uzY/S0GNBX5AAye1o4oE9k1cTXM5MVwgGR5dT7tW48uOR7utGiphx/AoGAETRo
22
+Q9OhSf0d8wivlq56sFg3Qpi3AB7LHp6o803a1qE3NWPy474tMObpdgvKsL3iTtXo
23
+zMZ+dOoG75whqVxm6UgrEMVrXxAs/TLAaP89/JYSd4J1ura7q22TdW8ROi5xDlt1
24
+YGvYl1uBc+IXeX7OE98qBnGLDF7y1DvTarkNFTkCgYEAh8/E5jzuCVNSScwgxbr4
25
+YAskfM9SkB3qW7ZKHmc+Oph3JGoGsS8MRMvUsOLLKNxuLbHNcUth44vyM4gsJaX9
26
+yBoBK/Or3R0xCNWj/2esbUxm1sTtJgn5k3xi3sPcoK0Lvm+7NoY8kpOJCzyfK+LO
27
+JtEftykJxRpr5BWu60ivaP4=
28
+-----END PRIVATE KEY-----

+ 26
- 0
_wildcard.gdzcfw.com.pem View File

@@ -0,0 +1,26 @@
1
+-----BEGIN CERTIFICATE-----
2
+MIIEYTCCAsmgAwIBAgIQeLnoo82DFqivTPiEiQbhcDANBgkqhkiG9w0BAQsFADCB
3
+lTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTUwMwYDVQQLDCxERVNL
4
+VE9QLUpVRTZKMjRcY2hlbmJpbmdyb25nQERFU0tUT1AtSlVFNkoyNDE8MDoGA1UE
5
+AwwzbWtjZXJ0IERFU0tUT1AtSlVFNkoyNFxjaGVuYmluZ3JvbmdAREVTS1RPUC1K
6
+VUU2SjI0MB4XDTI0MDUxNzA4MTEzMloXDTI2MDgxNzA4MTEzMlowYDEnMCUGA1UE
7
+ChMebWtjZXJ0IGRldmVsb3BtZW50IGNlcnRpZmljYXRlMTUwMwYDVQQLDCxERVNL
8
+VE9QLUpVRTZKMjRcY2hlbmJpbmdyb25nQERFU0tUT1AtSlVFNkoyNDCCASIwDQYJ
9
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALmvQC55rRpZRL+lplpQ/ayjfOiX0+jJ
10
+M5wy8wOuDLuGShXxmVSfymeZnMjXvu8bMJRf9UAzanjinL4+hhu0Fhg4FQf9zBzD
11
+ne2+cOfhAMmwOx9gUn5BVjiNsuuXxpA4WO0biLQ0LDlUwq57Jf9u7vZzP2mM3zPN
12
+f96S36rImAAf/c/ZU5pa0J7YtWnG2olJ2ph3LiesMZ4cTqsfBD/ReDZNX2y+Un9D
13
+7n0BDFUWRHGIBGYbwpeXOQSQdbEFa09YZHEhoJK/TMUDVkbuRy2JQ6aU+0sh7znM
14
+RZyJxooVEy/KYJUKS27VhCvXa9SFJLGRrmW5lJ1A8JQwebrNcSvc0jcCAwEAAaNh
15
+MF8wDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQY
16
+MBaAFMilcisfUK+WeFLd5wBZwQFoTE6lMBcGA1UdEQQQMA6CDCouZ2R6Y2Z3LmNv
17
+bTANBgkqhkiG9w0BAQsFAAOCAYEAijqEzcTRHF5fH6q8yfQoH+HE02/0TyP+Xhwd
18
+9X4kXSNBo9LbvSGHuwx60d9u8y/3nHs3brEBYPbBNOfAS6B1MxqfyvSF4YtJHedA
19
+BKHJZsK0nHkTnq/Ohz3p9hx5wl4d6SjEsUddJYzvWBF3YNY6csdm4ZRHX2/IURKa
20
+u/j1tNVI2EFccREk5kY6O1CogGp0WK3Du3sNOYw9FtUDQbYP1w00K99SX076YPwB
21
+DdkCe+xwNApYwX2tWP2995BkEn9x5iRP4gRKXeJPLhh4ZrwJQFa3wgzs5D12gMse
22
+W7X08PmQKIu6rySyRkEih4/8YQY9TTXdWVikydh+Zbkdqy9lBKvEBsysgGzEJhkn
23
+qvSwCu0gBmVxBwK4tPKv7PJHf/fGgFbvryqnnxfZzWumHfluBJ4CzDEDl/Rj10H6
24
+QNVUAKjNyTdKuiF0bV7ZhgKVvg6EAyK0emhZK2HVpfadp03Za14npAGFn5GxFxQJ
25
+VLGKBY4khnVlUZuPe2CcyiWKxWoU
26
+-----END CERTIFICATE-----

+ 1
- 0
application/.htaccess View File

@@ -0,0 +1 @@
1
+deny from all

+ 179
- 0
application/admin/behavior/ActionBeginBehavior.php View File

@@ -0,0 +1,179 @@
1
+<?php
2
+
3
+namespace app\admin\behavior;
4
+
5
+use think\Db;
6
+
7
+/**
8
+ * 系统行为扩展:新增/更新/删除之后的后置操作
9
+ */
10
+load_trait('controller/Jump');
11
+class ActionBeginBehavior {
12
+    use \traits\controller\Jump;
13
+    protected static $actionName;
14
+    protected static $controllerName;
15
+    protected static $moduleName;
16
+    protected static $method;
17
+
18
+    /**
19
+     * 构造方法
20
+     * @param Request $request Request对象
21
+     * @access public
22
+     */
23
+    public function __construct()
24
+    {
25
+
26
+    }
27
+
28
+    // 行为扩展的执行入口必须是run
29
+    public function run(&$params){
30
+        self::$actionName = request()->action();
31
+        self::$controllerName = request()->controller();
32
+        self::$moduleName = request()->module();
33
+        self::$method = request()->method();
34
+        $this->_initialize();
35
+    }
36
+
37
+    private function _initialize() {
38
+        $this->security_verify();
39
+        if ('POST' == self::$method) {
40
+            $this->clearWeapp();
41
+            $this->instyes();
42
+        } else {
43
+            $this->unotice();
44
+            $this->verifyfile();
45
+        }
46
+        $this->language_access();
47
+    }
48
+
49
+    /**
50
+     * 多语言功能操作权限
51
+     * @return [type] [description]
52
+     */
53
+    private function language_access()
54
+    {
55
+        $controllerArr = ['Weapp','Filemanager','Sitemap','Member','Seo','Channeltype','Tools'];
56
+        $ctlActArr = ['Admin@index','Admin@add','Admin@del','System@water','System@thumb','System@api_conf'];
57
+        if (in_array(self::$controllerName, $controllerArr) || in_array(self::$controllerName.'@'.self::$actionName, $ctlActArr)) {
58
+            $main_lang = get_main_lang();
59
+            $admin_lang = get_admin_lang();
60
+            if (is_language() && $main_lang != $admin_lang) {
61
+                $lang_title = model('Language')->where('mark',$main_lang)->value('title');
62
+                $this->error('当前语言没有此功能,请切换到【'.$lang_title.'】语言');
63
+            }
64
+        }
65
+    }
66
+
67
+    private function security_verify()
68
+    {
69
+        $ctl_act = self::$controllerName.'@'.self::$actionName;
70
+        if (in_array(self::$controllerName, ['Filemanager', 'Weapp']) || in_array($ctl_act, ['Arctype@ajax_newtpl','Archives@ajax_newtpl'])) {
71
+            $security = tpSetting('security');
72
+
73
+            /*---------强制必须开启密保问题认证 start----------*/
74
+            if (in_array(self::$controllerName, ['Filemanager']) || in_array($ctl_act, ['Arctype@ajax_newtpl','Archives@ajax_newtpl'])) {
75
+                if (empty($security['security_ask_open'])) {
76
+                    $this->error("<span style='display:none;'>__html__</span>需要开启密保问题设置", url('Security/index'), '', 3);
77
+                }
78
+            }
79
+            /*---------强制必须开启密保问题认证 end----------*/
80
+
81
+            $nosubmit = input('param.nosubmit/d');
82
+            if ('POST' == self::$method && empty($nosubmit)) {
83
+                if (empty($security['security_ask_open']) || !security_verify_func($ctl_act)) {
84
+                    return true;
85
+                }
86
+                $admin_id = session('?admin_id') ? (int)session('admin_id') : 0;
87
+                $admin_info = Db::name('admin')->field('admin_id,last_ip')->where(['admin_id'=>$admin_id])->find();
88
+                // 当前管理员密保问题验证过的IP地址
89
+                $security_answerverify_ip = !empty($security['security_answerverify_ip']) ? $security['security_answerverify_ip'] : '-1';
90
+                // 同IP不验证
91
+                if ($admin_info['last_ip'] == $security_answerverify_ip) {
92
+                    return true;
93
+                }
94
+
95
+                $this->error("<span style='display:none;'>__html__</span>出于安全考虑<br/>请勿非法越过密保答案验证", null, '', 3);
96
+            }
97
+        }
98
+    }
99
+
100
+    private function verifyfile()
101
+    {
102
+        $tmp1 = 'cGhwLnBocF9zZXJ2aW'.'NlaW5mbw==';
103
+        $tmp1 = base64_decode($tmp1);
104
+        $data = tpCache($tmp1);
105
+        $data = mchStrCode($data, 'DECODE');
106
+        $data = json_decode($data, true);
107
+        if (empty($data['pid']) || 2 > $data['pid']) return true;
108
+        $file = "./data/conf/{$data['code']}.txt";
109
+        $tmp2 = 'cGhwX3NlcnZpY2VtZWFs';
110
+        $tmp2 = base64_decode($tmp2);
111
+        if (!file_exists($file)) {
112
+            /*多语言*/
113
+            if (is_language()) {
114
+                $langRow = \think\Db::name('language')->order('id asc')->select();
115
+                foreach ($langRow as $key => $val) {
116
+                    tpCache('php', [$tmp2=>1], $val['mark']);
117
+                }
118
+            } else { // 单语言
119
+                tpCache('php', [$tmp2=>1]);
120
+            }
121
+            /*--end*/
122
+        } else {
123
+            /*多语言*/
124
+            if (is_language()) {
125
+                $langRow = \think\Db::name('language')->order('id asc')->select();
126
+                foreach ($langRow as $key => $val) {
127
+                    tpCache('php', [$tmp2=>$data['pid']], $val['mark']);
128
+                }
129
+            } else { // 单语言
130
+                tpCache('php', [$tmp2=>$data['pid']]);
131
+            }
132
+            /*--end*/
133
+        }
134
+    }
135
+
136
+    private function unotice(){
137
+        $str = 'VXNlcnNOb3RpY2U=';
138
+        if (self::$controllerName == base64_decode($str)) {
139
+            $str = 'd2ViLndlYl9pc19hdXRob3J0b2tlbg==';
140
+            $value = tpCache(base64_decode($str));
141
+            if (-1 == $value) {
142
+                $str = '6K+l5Yqf6IO95LuF6ZmQ5LqO5ZWG5Lia5o6I5p2D5Z+f5ZCN77yB';
143
+                $this->error(base64_decode($str));
144
+            }
145
+        }
146
+    }
147
+
148
+    /**
149
+     * 插件每次post提交都清除插件相关缓存
150
+     * @access private
151
+     */
152
+    private function clearWeapp()
153
+    {
154
+        /*只有相应的控制器和操作名才执行,以便提高性能*/
155
+        $ctlActArr = array(
156
+            'Weapp@*',
157
+        );
158
+        $ctlActStr = self::$controllerName.'@*';
159
+        if (in_array($ctlActStr, $ctlActArr)) {
160
+            \think\Cache::clear('hooks');
161
+        }
162
+        /*--end*/
163
+    }
164
+
165
+    /**
166
+     * @access private
167
+     */
168
+    private function instyes()
169
+    {
170
+        $ca = md5(self::$actionName.'@'.self::$controllerName);
171
+        if ('0e3e00da04fcf78cd9fd7dc763d956fc' == $ca) {
172
+            $s = '5a6J'.'6KOF'.'5oiQ5'.'Yqf';
173
+            if (1605110400 < getTime()) {
174
+                sleep(5);
175
+                $this->success(base64_decode($s));
176
+            }
177
+        }
178
+    }
179
+}

+ 149
- 0
application/admin/behavior/AppEndBehavior.php View File

@@ -0,0 +1,149 @@
1
+<?php
2
+
3
+namespace app\admin\behavior;
4
+
5
+use think\Db;
6
+
7
+/**
8
+ * 系统行为扩展:
9
+ */
10
+class AppEndBehavior {
11
+    protected static $actionName;
12
+    protected static $controllerName;
13
+    protected static $moduleName;
14
+    protected static $method;
15
+
16
+    /**
17
+     * 构造方法
18
+     * @param Request $request Request对象
19
+     * @access public
20
+     */
21
+    public function __construct()
22
+    {
23
+
24
+    }
25
+
26
+    // 行为扩展的执行入口必须是run
27
+    public function run(&$params){
28
+        self::$actionName = request()->action();
29
+        self::$controllerName = request()->controller();
30
+        self::$moduleName = request()->module();
31
+        self::$method = request()->method();
32
+        // file_put_contents ( DATA_PATH."log.txt", date ( "Y-m-d H:i:s" ) . "  " . var_export('admin_CoreProgramBehavior',true) . "\r\n", FILE_APPEND );
33
+        $this->_initialize();
34
+    }
35
+
36
+    private function _initialize() {
37
+        $this->resetAuthor(); // 临时处理授权问题
38
+        $this->clearHtmlCache(); // 变动数据之后,清除页面缓存和数据
39
+        $this->eyou_statistics_data(); // 商城主题欢迎页的数据统计
40
+    }
41
+
42
+    /**
43
+     * 临时处理授权问题
44
+     */
45
+    private function resetAuthor()
46
+    {
47
+        /*在以下相应的控制器和操作名里执行,以便提高性能*/
48
+        $ctlActArr = array(
49
+            'Index@index',
50
+        );
51
+        $ctlActStr = self::$controllerName.'@'.self::$actionName;
52
+        if (in_array($ctlActStr, $ctlActArr) && 'GET' == self::$method) {
53
+            if(!empty($_SESSION['isset_resetAuthor']))
54
+                return true;
55
+            $_SESSION['isset_resetAuthor'] = 1;
56
+
57
+            session('isset_author', null);
58
+        }
59
+        /*--end*/
60
+    }
61
+
62
+    /**
63
+     * 数据变动之后,清理页面和数据缓存
64
+     */
65
+    private function clearHtmlCache()
66
+    {
67
+        /*在以下相应的控制器和操作名里执行,以便提高性能*/
68
+        $actArr = ['add','edit','del','recovery','changeTableVal'];
69
+        if ('POST' == self::$method) {
70
+            foreach ($actArr as $key => $val) {
71
+                if (preg_match('/^((.*)_)?('.$val.')$/i', self::$actionName) || preg_match('/^(ajax_)?'.$val.'(_(.*))?$/i', self::$actionName)) {
72
+                    $aids = [];
73
+                    if (!empty($_POST['aids'])) {
74
+                        $aids = $_POST['aids'];
75
+                    } else if (!empty($_POST['aid'])) {
76
+                        $aids = [$_POST['aid']];
77
+                    }
78
+
79
+                    $typeids = [];
80
+                    if (!empty($_POST['typeids'])) {
81
+                        $typeids = $_POST['typeids'];
82
+                    } else if (!empty($_POST['typeid'])) {
83
+                        $typeids = [$_POST['typeid']];
84
+                    }
85
+                    clearHtmlCache($aids, $typeids);
86
+                    // \think\Cache::clear();
87
+                    // delFile(HTML_ROOT.'index');
88
+                    break;
89
+                }
90
+            }
91
+        }
92
+    }
93
+
94
+    /**
95
+     * 商城主题欢迎页的数据统计写入
96
+     * @return [type] [description]
97
+     */
98
+    private function eyou_statistics_data()
99
+    {
100
+        if ('POST' == self::$method) {
101
+            if (in_array(self::$controllerName, ['Product','ShopProduct','Article']) && in_array(self::$actionName, ['add'])) { // 新增商品
102
+                if (in_array(self::$controllerName, ['Article'])) {
103
+                    eyou_statistics_data(7);
104
+                } else if (in_array(self::$controllerName, ['Product','ShopProduct'])) {
105
+                    eyou_statistics_data(6);
106
+                }
107
+            } else if (in_array(self::$controllerName, ['RecycleBin']) && in_array(self::$actionName, ['archives_recovery'])) { // 恢复商品
108
+                //查一下删除的商品里有没有昨天和今天发布的 要在统计里减去
109
+                $rec_aid = is_array($_POST) ? $_POST : [$_POST['del_id']];
110
+                if (!empty($rec_aid)) {
111
+                    $ystd_count = $td_count = 0;
112
+                    $today = strtotime(date('Y-m-d'));
113
+                    $yesterday = $today - 86400;
114
+                    $where = [
115
+                        'aid' => ['IN', $rec_aid],
116
+                        'add_time' => ['egt', $yesterday],
117
+                    ];
118
+                    $list = Db::name('archives')->field('aid,add_time')->where($where)->select();
119
+                    foreach ($list as $key => $val) {
120
+                        if ($val['add_time'] < $today) { // 昨天统计
121
+                            $ystd_count++;
122
+                        } else if ($val['add_time'] >= $today) { // 今天统计
123
+                            $td_count++;
124
+                        }
125
+                    }
126
+                    if (in_array(self::$controllerName, ['Article'])) {
127
+                        $this->del_statistics(7,$td_count,$ystd_count,'inc');
128
+                    } else if (in_array(self::$controllerName, ['Product','ShopProduct'])) {
129
+                        $this->del_statistics(6,$td_count,$ystd_count,'inc');
130
+                    }
131
+                }
132
+            }
133
+        }
134
+    }
135
+
136
+    /**
137
+     * @param string $action inc 增加 dec 减少
138
+     */
139
+    private function del_statistics($type, $td_count = 0,$ystd_count = 0,$action = 'inc'){
140
+        //写入统计 减去
141
+        if ($td_count > 0){
142
+            eyou_statistics_data($type,$td_count,'',$action);//今天的
143
+        }
144
+        if ($ystd_count > 0){
145
+            $ystd = strtotime('-1 day');
146
+            eyou_statistics_data($type,$ystd_count,$ystd,$action);//昨天的
147
+        }
148
+    }
149
+}

+ 285
- 0
application/admin/behavior/AuthRoleBehavior.php View File

@@ -0,0 +1,285 @@
1
+<?php
2
+
3
+namespace app\admin\behavior;
4
+
5
+/**
6
+ * 管理员权限控制
7
+ */
8
+load_trait('controller/Jump');
9
+class AuthRoleBehavior
10
+{
11
+    use \traits\controller\Jump;
12
+    protected static $actionName;
13
+    protected static $controllerName;
14
+    protected static $moduleName;
15
+    protected static $method;
16
+    protected static $admin_info;
17
+
18
+    /**
19
+     * 构造方法
20
+     * @param Request $request Request对象
21
+     * @access public
22
+     */
23
+    public function __construct()
24
+    {
25
+        !isset(self::$moduleName) && self::$moduleName = request()->module();
26
+        !isset(self::$controllerName) && self::$controllerName = request()->controller();
27
+        !isset(self::$actionName) && self::$actionName = request()->action();
28
+        !isset(self::$method) && self::$method = request()->method();
29
+        !isset(self::$admin_info) && self::$admin_info = session('admin_info');
30
+    }
31
+
32
+    /**
33
+     * 模块初始化
34
+     * @param array $params 传入参数
35
+     * @access public
36
+     */
37
+    public function moduleInit(&$params)
38
+    {
39
+
40
+    }
41
+
42
+    /**
43
+     * 操作开始执行
44
+     * @param array $params 传入参数
45
+     * @access public
46
+     */
47
+    public function actionBegin(&$params)
48
+    {
49
+        if (0 < intval(self::$admin_info['role_id'])) {
50
+            // 检测全局的增、改、删的权限——优先级最高
51
+            $this->cud_access();
52
+            // 检测每个小插件的权限
53
+            $this->weapp_access();
54
+            // 检测栏目管理的每个栏目权限
55
+            $this->arctype_access();
56
+            // 检测内容管理每个栏目对应的内容里列表等权限
57
+            $this->archives_access();
58
+        }
59
+    }
60
+
61
+    /**
62
+     * 视图内容过滤
63
+     * @param array $params 传入参数
64
+     * @access public
65
+     */
66
+    public function viewFilter(&$params)
67
+    {
68
+
69
+    }
70
+
71
+    /**
72
+     * 应用结束
73
+     * @param array $params 传入参数
74
+     * @access public
75
+     */
76
+    public function appEnd(&$params)
77
+    {
78
+
79
+    }
80
+
81
+    /**
82
+     * 检测全局的增、改、删的权限
83
+     * @access private
84
+     */
85
+    private function cud_access()
86
+    {
87
+        /*只有相应的控制器和操作名才执行,以便提高性能*/
88
+        $ctl = strtolower(self::$controllerName);
89
+        $act = strtolower(self::$actionName);
90
+        if ('archives' == $ctl && in_array($act, ['check','uncheck'])) { // 审核信息\取消审核信息
91
+            $act = 'changetableval';
92
+        }
93
+
94
+        $actArr = ['add','edit','del'];
95
+        if ('weapp' == $ctl && 'execute' == $act) {
96
+            $sa = input('param.sa/s');
97
+            foreach ($actArr as $key => $cud) {
98
+                $sa = preg_replace('/^(.*)_('.$cud.')$/i', '$2', $sa); // 同名add 或者以_add类似结尾都符合
99
+                if ($sa == $cud) {
100
+                    $admin_info = self::$admin_info;
101
+                    $auth_role_info = !empty($admin_info['auth_role_info']) ? $admin_info['auth_role_info'] : [];
102
+                    $cudArr = !empty($auth_role_info['cud']) ? $auth_role_info['cud'] : [];
103
+                    if (!in_array($sa, $cudArr)) {
104
+                        $this->error('您没有操作权限,请联系超级管理员分配权限');
105
+                    }
106
+                    break;
107
+                }
108
+            }
109
+        } else {
110
+            $post = input('post.');
111
+            array_push($actArr, 'changetableval'); // 审核信息
112
+            foreach ($actArr as $key => $cud) {
113
+                $act = preg_replace('/^(.*)_('.$cud.')$/i', '$2', $act); // 同名add 或者以_add类似结尾都符合
114
+                if ($act == $cud) {
115
+                    $admin_info = self::$admin_info;
116
+                    $auth_role_info = !empty($admin_info['auth_role_info']) ? $admin_info['auth_role_info'] : [];
117
+                    $cudArr = !empty($auth_role_info['cud']) ? $auth_role_info['cud'] : [];
118
+                    if (!in_array($act, $cudArr)) {
119
+                        if ('changetableval' == $act && 'index' == $ctl) {
120
+                            // 审核信息
121
+                            if ('archives' == $post['table'] && 'arcrank' == $post['field']) {
122
+                                $this->error('您没有操作权限,请联系超级管理员分配权限', null, '', 2);
123
+                            }
124
+                        } else {
125
+                            $this->error('您没有操作权限,请联系超级管理员分配权限');
126
+                        }
127
+                    } else {
128
+                        if (!in_array('changetableval', $cudArr)) {
129
+                            // 审核信息
130
+                            if (IS_POST && 'edit' == $act) {
131
+                                $archivesInfo = M('archives')->field('arcrank,admin_id')->find($post['aid']);
132
+                                if (-1 == $archivesInfo['arcrank'] && isset($post['arcrank']) && $archivesInfo['arcrank'] != $post['arcrank']) {
133
+                                    $this->error('您没有操作权限,请联系超级管理员分配权限', url('Archives/edit', ['id'=>$post['aid']]), '', 3);
134
+                                }
135
+                            }
136
+                        }
137
+                    }
138
+                    break;
139
+                }
140
+            }
141
+        }
142
+        /*--end*/
143
+    }
144
+
145
+    /**
146
+     * 检测每个小插件的权限
147
+     * @access private
148
+     */
149
+    private function weapp_access()
150
+    {
151
+        /*只有相应的控制器和操作名才执行,以便提高性能*/
152
+        $ctl = strtolower(self::$controllerName);
153
+        $act = strtolower(self::$actionName);
154
+        if ('weapp' == $ctl) {
155
+            if ('execute' == $act) {
156
+                $sc = input('param.sc/s');
157
+                $sm = input('param.sm/s');
158
+                $sa = input('param.sa/s');
159
+                $admin_info = self::$admin_info;
160
+                $auth_role_info = !empty($admin_info['auth_role_info']) ? $admin_info['auth_role_info'] : [];
161
+                $plugins = !empty($auth_role_info['permission']['plugins']) ? $auth_role_info['permission']['plugins'] : [];
162
+                // 插件本身设置的权限列表
163
+                $config = include WEAPP_PATH.$sm.DS.'config.php';
164
+                $plugins_permission = !empty($config['permission']) ? array_keys($config['permission']) : [];
165
+                // 管理员拥有的插件具体权限
166
+                $admin_permission = !empty($plugins[$sm]['child']) ? $plugins[$sm]['child'] : [];
167
+                // 没有赋给管理员的插件具体权限
168
+                $diff_plugins_perm = array_diff($plugins_permission, $admin_permission);
169
+                // 检测插件权限
170
+                $bool = true;
171
+                if (empty($plugins_permission) && !isset($plugins[$sm])) {
172
+                    $bool = false;
173
+                } else if (!empty($plugins_permission)) {
174
+                    foreach ($diff_plugins_perm as $key => $val) {
175
+                        if (strtolower($sm.'@'.$sa) == strtolower($val)) {
176
+                            $bool = false;
177
+                            break;
178
+                        }
179
+                    }
180
+                }
181
+                if (!$bool) {
182
+                    $this->error('您没有操作权限,请联系超级管理员分配权限');
183
+                }
184
+            } else if (in_array($act, ['plugin','mybuy'])) {
185
+                if (0 < intval(session('admin_info.role_id'))) {
186
+                    $this->error('您没有操作权限,只允许创始人和超级管理员操作');
187
+                }
188
+            }
189
+        }
190
+        /*--end*/
191
+    }
192
+
193
+    /**
194
+     * 检测栏目管理的每个栏目权限
195
+     * @access private
196
+     */
197
+    private function arctype_access()
198
+    {
199
+        /*只有相应的控制器和操作名才执行,以便提高性能*/
200
+        $ctl_all = strtolower(self::$controllerName.'@*');
201
+        $ctlArr = ['arctype@*'];
202
+        if (in_array($ctl_all, $ctlArr)) {
203
+            $typeids = [];
204
+            if (in_array(strtolower(self::$actionName), ['edit','del'])) {
205
+                $typeids[] = input('id/d', 0);
206
+            } else if (in_array(strtolower(self::$actionName), ['add'])) {
207
+                $typeids[] = input('parent_id/d', 0);
208
+            }
209
+            if (!$this->is_check_arctype($typeids)) {
210
+                $this->error('您没有操作权限,请联系超级管理员分配权限');
211
+            }
212
+        }
213
+        /*--end*/
214
+    }
215
+
216
+    /**
217
+     * 检测内容管理每个栏目对应的内容里列表等权限
218
+     * @access private
219
+     */
220
+    private function archives_access()
221
+    {
222
+        /*只有相应的控制器和操作名才执行,以便提高性能*/
223
+        $ctl = strtolower(self::$controllerName);
224
+        $act = strtolower(self::$actionName);
225
+        $ctl_act = $ctl.'@'.$act;
226
+        $ctl_all = $ctl.'@*';
227
+
228
+        $ctlArr= ['arctype@single','archives@*'];
229
+        $row = \think\Db::name('channeltype')
230
+            ->where('nid','NOTIN', ['single'])
231
+            ->column('ctl_name');
232
+        foreach ($row as $key => $val) {
233
+            array_push($ctlArr, strtolower($val).'@*');
234
+        }
235
+        if (in_array($ctl_act, $ctlArr) || in_array($ctl_all, $ctlArr)) {
236
+            $typeids = [];
237
+            if (in_array($act, ['add','edit','del'])) {
238
+                $aids = [];
239
+                switch ($act) {
240
+                    case 'edit':
241
+                        $aids = input('id/a', []);
242
+                        break;
243
+
244
+                    case 'del':
245
+                        $aids = input('del_id/a', []);
246
+                        break;
247
+                    
248
+                    default:
249
+                        # code...
250
+                        break;
251
+                }
252
+                if (!empty($aids)) {
253
+                    $typeids = M('archives')->where('aid','IN',$aids)->column('typeid');
254
+                }
255
+            } else {
256
+                $typeids[] = input('typeid/d', 0);
257
+            }
258
+            if (!$this->is_check_arctype($typeids)) {
259
+                $this->error('您没有操作权限,请联系超级管理员分配权限');
260
+            }
261
+        }
262
+        /*--end*/
263
+    }
264
+
265
+    /**
266
+     * 检测栏目是否有权限
267
+     */
268
+    private function is_check_arctype($typeids = []) {  
269
+        $bool_flag = true;
270
+        $admin_info = self::$admin_info;
271
+        if (0 < intval($admin_info['role_id'])) {
272
+            $auth_role_info = $admin_info['auth_role_info'];
273
+            $permission = $auth_role_info['permission'];
274
+
275
+            foreach ($typeids as $key => $tid) {
276
+                if (0 < intval($tid) && !in_array($tid, $permission['arctype'])) {
277
+                    $bool_flag = false;
278
+                    break;
279
+                }
280
+            }
281
+        }
282
+
283
+        return $bool_flag;
284
+    }
285
+}

+ 71
- 0
application/admin/behavior/ModuleInitBehavior.php View File

@@ -0,0 +1,71 @@
1
+<?php
2
+
3
+namespace app\admin\behavior;
4
+
5
+use think\Config;
6
+
7
+/**
8
+ * 系统行为扩展:
9
+ */
10
+class ModuleInitBehavior {
11
+    protected static $actionName;
12
+    protected static $controllerName;
13
+    protected static $moduleName;
14
+    protected static $method;
15
+
16
+    /**
17
+     * 构造方法
18
+     * @param Request $request Request对象
19
+     * @access public
20
+     */
21
+    public function __construct()
22
+    {
23
+
24
+    }
25
+
26
+    // 行为扩展的执行入口必须是run
27
+    public function run(&$params){
28
+        self::$actionName = request()->action();
29
+        self::$controllerName = request()->controller();
30
+        self::$moduleName = request()->module();
31
+        self::$method = request()->method();
32
+        $this->_initialize();
33
+    }
34
+
35
+    private function _initialize() {
36
+        $this->vertifyCode();
37
+    }
38
+
39
+    /**
40
+     * 登录 - 验证码
41
+     * @param array $params 传入参数
42
+     * @access public
43
+     */
44
+    private function vertifyCode()
45
+    {
46
+        /*只有相应的控制器和操作名才执行,以便提高性能*/
47
+        $ctlActArr = array(
48
+            'Admin@login',
49
+            'Admin@vertify',
50
+        );
51
+        $ctlActStr = self::$controllerName.'@'.self::$actionName;
52
+        if (in_array($ctlActStr, $ctlActArr)) {
53
+            $row = tpSetting('system.system_vertify');
54
+            // 获取验证码配置信息
55
+            $row = json_decode($row, true);
56
+            $baseConfig = Config::get("captcha");
57
+            if (!empty($row)) {
58
+                foreach ($row['captcha'] as $key => $val) {
59
+                    if ('default' == $key) {
60
+                        $baseConfig[$key] = array_merge($baseConfig[$key], $val);
61
+                    } else {
62
+                        $baseConfig[$key]['is_on'] = $val['is_on'];
63
+                        $baseConfig[$key]['config'] = array_merge($baseConfig['default'], $val['config']);
64
+                    }
65
+                }
66
+            }
67
+
68
+            Config::set('captcha', $baseConfig);
69
+        }
70
+    }
71
+}

+ 239
- 0
application/admin/behavior/ViewFilterBehavior.php View File

@@ -0,0 +1,239 @@
1
+<?php
2
+
3
+namespace app\admin\behavior;
4
+
5
+use think\Db;
6
+
7
+/**
8
+ * 系统行为扩展:
9
+ */
10
+class ViewFilterBehavior {
11
+    protected static $actionName;
12
+    protected static $controllerName;
13
+    protected static $moduleName;
14
+    protected static $method;
15
+
16
+    /**
17
+     * 构造方法
18
+     * @param Request $request Request对象
19
+     * @access public
20
+     */
21
+    public function __construct()
22
+    {
23
+
24
+    }
25
+
26
+    // 行为扩展的执行入口必须是run
27
+    public function run(&$params){
28
+        self::$actionName = request()->action();
29
+        self::$controllerName = request()->controller();
30
+        self::$moduleName = request()->module();
31
+        self::$method = request()->method();
32
+        $this->_initialize($params);
33
+    }
34
+
35
+    private function _initialize(&$params) {
36
+        $this->security_verify($params);
37
+        // $this->weappUpgrade($params);
38
+    }
39
+
40
+    private function security_verify(&$params)
41
+    {
42
+        $ctl_act = self::$controllerName.'@'.self::$actionName;
43
+        if ('GET' == self::$method && in_array(self::$controllerName, ['Filemanager', 'Weapp']) || in_array($ctl_act, ['Arctype@ajax_newtpl','Archives@ajax_newtpl'])) {
44
+            $security = tpSetting('security');
45
+            if (empty($security['security_ask_open']) || !security_verify_func($ctl_act)) {
46
+                return true;
47
+            }
48
+            $admin_id = session('?admin_id') ? (int)session('admin_id') : 0;
49
+            $admin_info = Db::name('admin')->field('admin_id,last_ip')->where(['admin_id'=>$admin_id])->find();
50
+            // 当前管理员二次安全验证过的IP地址
51
+            $security_answerverify_ip = !empty($security['security_answerverify_ip']) ? $security['security_answerverify_ip'] : '-1';
52
+            // 同IP不验证
53
+            if ($admin_info['last_ip'] == $security_answerverify_ip) {
54
+                return true;
55
+            }
56
+
57
+            $security_ask = $security['security_ask'];
58
+            $url = url('Security/ajax_answer_verify', ['_ajax'=>1]);
59
+            $replace = <<<EOF
60
+    <script type="text/javascript">
61
+        $(function(){
62
+            autoload_security();
63
+            function autoload_security()
64
+            {
65
+                layer.prompt({
66
+                    title: '密保问题',
67
+                    id: 'layerid_1645598368',
68
+                    btn: ['确定'],
69
+                    shade: layer_shade,
70
+                    closeBtn: 3,
71
+                    success: function(layero, index) {
72
+                        var before_str = "<div style='margin: -8px 0px 10px 0px;color: red;font-weight: bold;'>{$security_ask}</div>";
73
+                        $("#layerid_1645598368").prepend(before_str);
74
+                        $("#layerid_1645598368").find('input').attr('placeholder', '请录入密保答案!');
75
+                        $("#layerid_1645598368").find('input').bind('keydown', function(event) {
76
+                            if (event.keyCode == 13) {
77
+                                security_answer_verify($(this).val());
78
+                            }
79
+                        });
80
+                    },
81
+                    btn2: function(index, layero){
82
+                        window.location.reload();
83
+                        return false;
84
+                    },
85
+                    cancel: function(index, layero){ 
86
+                        history.back();
87
+                        return false; 
88
+                    }
89
+                }, function(value, index) {
90
+                    security_answer_verify(value);
91
+                });
92
+            }
93
+
94
+            function security_answer_verify(answer)
95
+            {
96
+                $.ajax({
97
+                    type : 'post',
98
+                    url : "{$url}",
99
+                    data : {answer:answer},
100
+                    dataType : 'json',
101
+                    success : function(res){
102
+                        if (res.code == 1) {
103
+                            layer.closeAll();
104
+                            layer.msg(res.msg, {time: 1000}, function(){
105
+                                window.location.reload();
106
+                            });
107
+                        }else{
108
+                            $('#layerid_1645598368').find('input[type=text]').focus();
109
+                            layer.msg(res.msg, {time: 1000});
110
+                        }
111
+                    },
112
+                    error: function(e) {
113
+                        showErrorAlert(e.responseText);
114
+                    }
115
+                });
116
+            }
117
+        });
118
+    </script>
119
+EOF;
120
+
121
+            $params = str_ireplace('</body>', $replace, $params);
122
+        }
123
+    }
124
+
125
+    /**
126
+     * 每个插件主入口index页面进行更新包检测
127
+     */
128
+    private function weappUpgrade(&$params)
129
+    {
130
+        $code = input('param.sm/s');
131
+        $sc = input('param.sc/s');
132
+        $sa = input('param.sa/s');
133
+        $sca = $sc.'&'.$sa;
134
+        $ca = self::$controllerName.'&'.self::$actionName;
135
+        if ('Weapp&execute' == $ca && "{$code}&index" == $sca && 'GET' == self::$method && !isMobile()) {
136
+            if (!empty($code)) {
137
+                $url1 = url('Weapp/ajax_check_upgrade');
138
+                $url2 = url('Weapp/OneKeyUpgrade');
139
+                $url3 = url('Weapp/ajax_cancel_upgrade');
140
+                $replace = <<<EOF
141
+    <script type="text/javascript">
142
+        $(function(){
143
+
144
+            weapp_upgrade_1599613252();
145
+
146
+            // 检测升级
147
+            function weapp_upgrade_1599613252()
148
+            {
149
+                var code = '{$code}';
150
+                $.ajax({
151
+                    type : "GET",
152
+                    url  : "{$url1}",
153
+                    data : {code:code , _ajax:1},
154
+                    dataType: 'json',
155
+                    success: function(res) {
156
+                        if (res.code == 1 && res.data.upgrade && res.data.upgrade.code == 2) {
157
+                            var upgrade_str = res.data.upgrade.msg.upgrade;
158
+                            var intro_str = res.data.upgrade.msg.intro;
159
+                            var notice_str = res.data.upgrade.msg.notice;
160
+                            intro_str += '<style type="text/css">.layui-layer-content{height:270px!important;text-align:left!important;}</style>';
161
+                            upgrade_str = notice_str + intro_str + '<br/>' + upgrade_str;
162
+                            //询问框
163
+                            layer.confirm(upgrade_str, {
164
+                                shade: [0.7, '#fafafa'],
165
+                                area: ['580px','400px'],
166
+                                move: false,
167
+                                title: '新版本更新',
168
+                                btnAlign:'r',
169
+                                closeBtn: 3,
170
+                                btn: ['升级','不再提醒'], //按钮
171
+                                success: function () {
172
+                                    $(".layui-layer-content").css('text-align', 'left');
173
+                                }
174
+                            }, function(){
175
+                                layer.closeAll();
176
+                                setTimeout(function(){
177
+                                    upgrade_1599613252(code); // 请求后台
178
+                                },200);
179
+                                
180
+                            }, function(){  
181
+                                setTimeout(function(){
182
+                                    cancel_upgrade_1599613252(code);
183
+                                },200);
184
+                            });  
185
+                        }
186
+                    }
187
+                }); 
188
+            }
189
+
190
+            // 执行升级
191
+            function upgrade_1599613252(code){
192
+                layer_loading('升级中');
193
+                $.ajax({
194
+                    type : "GET",
195
+                    url  : "{$url2}",
196
+                    timeout : 360000, //超时时间设置,单位毫秒 设置了 1小时
197
+                    data : {code:code, _ajax:1},
198
+                    error: function(request) {
199
+                        layer.closeAll();
200
+                        layer.alert("升级失败!", {icon: 2, closeBtn: false, title:false}, function(){
201
+                            window.location.reload();
202
+                        });
203
+                    },
204
+                    success: function(res) {
205
+                        layer.closeAll();
206
+                        if(1 == res.code){
207
+                            layer.msg('已升级最新版本!', {time:1000}, function(){
208
+                                window.location.reload();
209
+                            });
210
+                        }
211
+                        else{
212
+                            layer.alert(res.msg, {icon: 2, closeBtn: false, title:false}, function(){
213
+                                window.location.reload();
214
+                            });
215
+                        }
216
+                    }
217
+                });                 
218
+            }
219
+
220
+            // 不再提醒
221
+            function cancel_upgrade_1599613252(code){
222
+                $.ajax({
223
+                    type : "GET",
224
+                    url  : "{$url3}",
225
+                    data : {code:code, _ajax:1},
226
+                    success: function(res) {
227
+                        
228
+                    }
229
+                });                 
230
+            }
231
+        });
232
+    </script>
233
+</body>
234
+EOF;
235
+                $params = str_ireplace('</body>', $replace, $params);
236
+            }
237
+        }
238
+    }
239
+}

+ 1407
- 0
application/admin/common.php
File diff suppressed because it is too large
View File


+ 449
- 0
application/admin/conf/auth_rule.php View File

@@ -0,0 +1,449 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+/**
15
+ * 权限属性说明
16
+ * array
17
+ *      id  主键ID
18
+ *      menu_id   一级模块ID
19
+ *      menu_id2    二级模块ID
20
+ *      name  权限名称
21
+ *      is_modules 是否显示在分组下
22
+ *      sort_order 排序号
23
+ *      auths 权限列表(格式:控制器@*,控制器@操作名 --多个权限以逗号隔开)
24
+ */
25
+return [
26
+    [
27
+        'id' => 1,
28
+        'menu_id' => 1001,
29
+        'menu_id2' => 0,
30
+        'name'  => '栏目管理',
31
+        'is_modules'    => 1,
32
+        'sort_order'    => 100,
33
+        'auths' => 'Arctype@index,Arctype@add,Arctype@edit,Arctype@del,Arctype@pseudo_del',
34
+    ],
35
+    [
36
+        'id' => 2,
37
+        'menu_id' => 1002,
38
+        'menu_id2' => 0,
39
+        'name'  => '内容管理',
40
+        'is_modules'    => 1,
41
+        'sort_order'    => 100,
42
+        'auths' => 'Archives@*,Arctype@single_edit,ShopProduct@attrlist_index',
43
+    ],
44
+    [
45
+        'id' => 3, // 广告管理
46
+        'menu_id' => 1003,
47
+        'menu_id2' => 0,
48
+        'name'  => '允许操作',
49
+        'is_modules'    => 1,
50
+        'sort_order'    => 100,
51
+        'auths' => 'Other@*,AdPosition@*',
52
+    ],
53
+    [
54
+        'id' => 4,
55
+        'menu_id' => 2001,
56
+        'menu_id2' => 2001001,
57
+        'name'  => '网站设置',
58
+        'is_modules'    => 1,
59
+        'sort_order'    => 10,
60
+        'auths' => 'System@web',
61
+    ],
62
+    [
63
+        'id' => 5,
64
+        'menu_id' => 2001,
65
+        'menu_id2' => 2001002,
66
+        'name'  => '核心设置',
67
+        'is_modules'    => 1,
68
+        'sort_order'    => 20,
69
+        'auths' => 'System@web2',
70
+    ],
71
+    [
72
+        'id' => 6,
73
+        'menu_id' => 2001,
74
+        'menu_id2' => 2001003,
75
+        'name'  => '附件设置',
76
+        'is_modules'    => 1,
77
+        'sort_order'    => 30,
78
+        'auths' => 'System@basic',
79
+    ],
80
+    [
81
+        'id' => 7,
82
+        'menu_id' => 2004,
83
+        'menu_id2' => 2004009,
84
+        'name'  => '水印配置',
85
+        'is_modules'    => 1,
86
+        'sort_order'    => 20,
87
+        'auths' => 'System@water',
88
+    ],
89
+    [
90
+        'id' => 8,
91
+        'menu_id' => 2003,
92
+        'menu_id2' => 2003001,
93
+        'name'  => 'URL配置',
94
+        'is_modules'    => 1,
95
+        'sort_order'    => 10,
96
+        'auths' => 'Seo@*',
97
+    ],
98
+    [
99
+        'id' => 9,
100
+        'menu_id' => 2003,
101
+        'menu_id2' => 2003003,
102
+        'name'  => '友情链接',
103
+        'is_modules'    => 1,
104
+        'sort_order'    => 30,
105
+        'auths' => 'Links@*',
106
+    ],
107
+    [
108
+        'id' => 10,
109
+        'menu_id' => 2004,
110
+        'menu_id2' => 2004001,
111
+        'name'  => '管理员',
112
+        'is_modules'    => 1,
113
+        'sort_order'    => 50,
114
+        'auths' => 'Admin@admin_pwd,Admin@index',
115
+    ],
116
+    [
117
+        'id' => 11,
118
+        'menu_id' => 2004,
119
+        'menu_id2' => 2004002,
120
+        'name'  => '备份还原',
121
+        'is_modules'    => 1,
122
+        'sort_order'    => 70,
123
+        'auths' => 'Tools@*',
124
+    ],
125
+    [
126
+        'id' => 12,
127
+        'menu_id' => 2004,
128
+        'menu_id2' => 2004003,
129
+        'name'  => '模板管理',
130
+        'is_modules'    => 1,
131
+        'sort_order'    => 100,
132
+        'auths' => 'Filemanager@*',
133
+    ],
134
+    [
135
+        'id' => 13,
136
+        'menu_id' => 2001,
137
+        'menu_id2' => 2001005,
138
+        'name'  => '接口配置',
139
+        'is_modules'    => 1,
140
+        'sort_order'    => 50,
141
+        'auths' => 'System@api_conf,System@smtp,System@smtp_tpl,System@smtp_tpl_edit,System@sms,System@sms_tpl,System@microsite,PayApi@*,Canal@*',
142
+    ],
143
+    // [
144
+    //     'id' => 14,
145
+    //     'menu_id' => 2004,
146
+    //     'menu_id2' => 2004005,
147
+    //     'name'  => '清除缓存',
148
+    //     'is_modules'    => 1,
149
+    //     'sort_order'    => 100,
150
+    //     'auths' => 'System@clear_cache',
151
+    // ],
152
+    [
153
+        'id' => 15,
154
+        'menu_id' => 2005,
155
+        'menu_id2' => 0,
156
+        'name'  => '插件应用',
157
+        'is_modules'    => 1,
158
+        'sort_order' => 100,
159
+        'auths' => 'Weapp@index,Weapp@create,Weapp@pack,Weapp@upload,Weapp@disable,Weapp@install,Weapp@enable,Weapp@execute',
160
+    ],
161
+    [
162
+        'id' => 16,
163
+        'menu_id' => 2002,
164
+        'menu_id2' => 0,
165
+        'name'  => '允许操作',
166
+        'is_modules'    => 1,
167
+        'sort_order'    => 100,
168
+        'auths' => 'Uiset@*',
169
+    ],
170
+    [
171
+        'id' => 17,
172
+        'menu_id' => 2005,
173
+        'menu_id2' => 0,
174
+        'name'  => '插件卸载',
175
+        'is_modules'    => 0,
176
+        'sort_order'    => 100,
177
+        'auths' => 'Weapp@uninstall',
178
+    ],
179
+    [
180
+        'id' => 18,
181
+        'menu_id' => 2004,
182
+        'menu_id2' => 2004100,
183
+        'name'  => '权限组',
184
+        'is_modules'    => 0,
185
+        'sort_order'    => 100,
186
+        'auths' => 'Admin@admin_add,Admin@admin_del,AuthRole@*',
187
+    ],
188
+    [
189
+        'id' => 19,
190
+        'menu_id' => 2004,
191
+        'menu_id2' => 2004006,
192
+        'name'  => '回收站',
193
+        'is_modules'    => 1,
194
+        'sort_order'    => 60,
195
+        'auths' => 'RecycleBin@*',
196
+    ],
197
+    [
198
+        'id' => 20,
199
+        'menu_id' => 2004,
200
+        'menu_id2' => 2004007,
201
+        'name'  => '频道模型',
202
+        'is_modules'    => 1,
203
+        'sort_order'    => 80,
204
+        'auths' => 'Channeltype@*,Field@*',
205
+    ],
206
+    [
207
+        'id' => 21,
208
+        'menu_id' => 2006,
209
+        'menu_id2' => 0,
210
+        'name'  => '允许操作',
211
+        'is_modules'    => 1,
212
+        'sort_order'    => 100,
213
+        'auths' => 'Member@*',
214
+    ],
215
+    [
216
+        'id' => 22,
217
+        'menu_id' => 2004,
218
+        'menu_id2' => 2004004,
219
+        'name'  => '栏目字段',
220
+        'is_modules'    => 1,
221
+        'sort_order'    => 90,
222
+        'auths' => 'Field@arctype_index,Field@arctype_add,Field@arctype_edit,Field@arctype_del',
223
+    ],
224
+    [
225
+        'id' => 23,
226
+        'menu_id' => 2008,
227
+        'menu_id2' => 0,
228
+        'name'  => '允许操作',
229
+        'is_modules'    => 1,
230
+        'sort_order'    => 100,
231
+        'auths' => 'Statistics@*,Shop@*,ShopProduct@*,Member@*',
232
+    ],
233
+    [
234
+        'id' => 24,
235
+        'menu_id' => 2009,
236
+        'menu_id2' => 0,
237
+        'name'  => '允许操作',
238
+        'is_modules'    => 1,
239
+        'sort_order'    => 100,
240
+        'auths' => 'Diyminipro@*',
241
+    ],
242
+    [
243
+        'id' => 25,
244
+        'menu_id' => 2003,
245
+        'menu_id2' => 2003002,
246
+        'name'  => 'Sitemap',
247
+        'is_modules'    => 1,
248
+        'sort_order'    => 20,
249
+        'auths' => 'Sitemap@*',
250
+    ],
251
+    [
252
+        'id' => 26,
253
+        'menu_id' => 2004,
254
+        'menu_id2' => 2004008,
255
+        'name'  => '文档属性',
256
+        'is_modules'    => 1,
257
+        'sort_order'    => 10,
258
+        'auths' => 'ArchivesFlag@*',
259
+    ],
260
+    [
261
+        'id' => 27,
262
+        'menu_id' => 2004,
263
+        'menu_id2' => 2004010,
264
+        'name'  => '缩略图配置',
265
+        'is_modules'    => 1,
266
+        'sort_order'    => 30,
267
+        'auths' => 'System@thumb',
268
+    ],
269
+    [
270
+        'id' => 28,
271
+        'menu_id' => 2004,
272
+        'menu_id2' => 2004011,
273
+        'name'  => 'TAG管理',
274
+        'is_modules'    => 1,
275
+        'sort_order'    => 40,
276
+        'auths' => 'Tags@*',
277
+    ],
278
+    [
279
+        'id' => 29,
280
+        'menu_id' => 2004,
281
+        'menu_id2' => 2004012,
282
+        'name'  => '模块开关',
283
+        'is_modules'    => 1,
284
+        'sort_order'    => 1,
285
+        'auths' => 'Index@switch_map_0',
286
+    ],
287
+    [
288
+        'id' => 30,
289
+        'menu_id' => 1004,
290
+        'menu_id2' => 0,
291
+        'name'  => '允许操作',
292
+        'is_modules'    => 1,
293
+        'sort_order'    => 100,
294
+        'auths' => 'Archives@index_draft',
295
+    ],
296
+    [
297
+        'id' => 31,
298
+        'menu_id' => 1005,
299
+        'menu_id2' => 1005001,
300
+        'name'  => '快捷导航',
301
+        'is_modules'    => 1,
302
+        'sort_order'    => 100,
303
+        'auths' => 'Index@ajax_quickmenu',
304
+    ],
305
+    [
306
+        'id' => 32,
307
+        'menu_id' => 1005,
308
+        'menu_id2' => 1005002,
309
+        'name'  => '内容统计',
310
+        'is_modules'    => 1,
311
+        'sort_order'    => 100,
312
+        'auths' => 'Index@ajax_content_total',
313
+    ],
314
+    [
315
+        'id' => 33,
316
+        'menu_id' => 2004,
317
+        'menu_id2' => 2004013,
318
+        'name'  => '导航管理',
319
+        'is_modules'    => 1,
320
+        'sort_order'    => 44,
321
+        'auths' => 'Navigation@*',
322
+    ],
323
+    [
324
+        'id' => 34,
325
+        'menu_id' => 2001,
326
+        'menu_id2' => 2001006,
327
+        'name'  => '自定义变量',
328
+        'is_modules'    => 1,
329
+        'sort_order'    => 60,
330
+        'auths' => 'System@customvar,System@customvar_index,System@customvar_save,System@customvar_del',
331
+    ],
332
+    [
333
+        'id' => 35,
334
+        'menu_id' => 2004,
335
+        'menu_id2' => 2004014,
336
+        'name'  => '站内通知',
337
+        'is_modules'    => 1,
338
+        'sort_order'    => 120,
339
+        'auths' => 'UsersNotice@*,Notify@*',
340
+    ],
341
+    [
342
+        'id' => 36,
343
+        'menu_id' => 2004,
344
+        'menu_id2' => 2004015,
345
+        'name'  => '验证码管理',
346
+        'is_modules'    => 1,
347
+        'sort_order'    => 110,
348
+        'auths' => 'Vertify@*',
349
+    ],
350
+    [
351
+        'id' => 37,
352
+        'menu_id' => 2004,
353
+        'menu_id2' => 2004016,
354
+        'name'  => 'html生成',
355
+        'is_modules'    => 1,
356
+        'sort_order'    => 106,
357
+        'auths' => 'Seo@build',
358
+    ],
359
+    [
360
+        'id' => 38,
361
+        'menu_id' => 2004,
362
+        'menu_id2' => 2004017,
363
+        'name'  => '安全中心',
364
+        'is_modules'    => 1,
365
+        'sort_order'    => 106,
366
+        'auths' => 'Security@*',
367
+    ],
368
+    [
369
+        'id' => 39,
370
+        'menu_id' => 2004,
371
+        'menu_id2' => 2004018,
372
+        'name'  => '留言管理',
373
+        'is_modules'    => 1,
374
+        'sort_order'    => 106,
375
+        'auths' => 'Form@*,Guestbook@details,Guestbook@del',
376
+    ],
377
+    [
378
+        'id' => 40,
379
+        'menu_id' => 2004,
380
+        'menu_id2' => 2004019,
381
+        'name'  => '城市分站',
382
+        'is_modules'    => 1,
383
+        'sort_order'    => 106,
384
+        'auths' => 'Citysite@*',
385
+    ],
386
+    [
387
+        'id' => 41,
388
+        'menu_id' => 2004,
389
+        'menu_id2' => 2004020,
390
+        'name'  => '当前导航',
391
+        'is_modules'    => 1,
392
+        'sort_order'    => 2,
393
+        'auths' => 'Index@switch_map_1',
394
+    ],
395
+    [
396
+        'id' => 42,
397
+        'menu_id' => 2004,
398
+        'menu_id2' => 2004021,
399
+        'name'  => '订单管理',
400
+        'is_modules'    => 1,
401
+        'sort_order'    => 120,
402
+        'auths' => 'Order@*',
403
+    ],
404
+    [
405
+        'id' => 43,
406
+        'menu_id' => 2004,
407
+        'menu_id2' => 2004022,
408
+        'name'  => '搜索管理',
409
+        'is_modules'    => 1,
410
+        'sort_order'    => 130,
411
+        'auths' => 'Search@*',
412
+    ],
413
+    [
414
+        'id' => 44,
415
+        'menu_id' => 2004,
416
+        'menu_id2' => 2004023,
417
+        'name'  => '积分兑换',
418
+        'is_modules'    => 1,
419
+        'sort_order'    => 140,
420
+        'auths' => 'Memgift@*',
421
+    ],
422
+    [
423
+        'id' => 46,
424
+        'menu_id' => 2004,
425
+        'menu_id2' => 2004025,
426
+        'name'  => '主题风格',
427
+        'is_modules'    => 1,
428
+        'sort_order'    => 107,
429
+        'auths' => 'Index@theme_index,Index@theme_conf,Index@theme_welcome_conf,Index@theme_add_login',
430
+    ],
431
+    [
432
+        'id' => 47,
433
+        'menu_id' => 2004,
434
+        'menu_id2' => 2004026,
435
+        'name'  => '外贸助手',
436
+        'is_modules'    => 1,
437
+        'sort_order'    => 108,
438
+        'auths' => 'Foreign@*',
439
+    ],
440
+    /*[
441
+        'id' => 48,
442
+        'menu_id' => 1006,
443
+        'menu_id2' => 0,
444
+        'name'  => '允许操作',
445
+        'is_modules'    => 1,
446
+        'sort_order'    => 100,
447
+        'auths' => 'Archives@index_reback',
448
+    ],*/
449
+];

+ 3
- 0
application/admin/conf/constant.php View File

@@ -0,0 +1,3 @@
1
+<?php
2
+define('INSTALL_DATE',1678496850);
3
+define('SERIALNUMBER','20230311090730mQsrNE');

+ 71
- 0
application/admin/conf/global.php View File

@@ -0,0 +1,71 @@
1
+<?php
2
+/**
3
+ * 配置常量
4
+ */
5
+$other_rele_menu = [];   //限制不显示的内容
6
+$main_lang = get_main_lang();
7
+$admin_lang = get_admin_lang();
8
+$globalConfig = tpCache('global');
9
+//其他语言,限制入口
10
+if ($main_lang != $admin_lang) {
11
+    $other_rele_menu = [1004,2004008,2004009,2004010,2004013,2004001,2004002,2004007,2004004,2004015,2004003,2004019,2004017,2004021,2008,2008001
12
+        ,2008002,2008003,2008008,2008004,2008005,2003,2004016,2003001,2003002,2005,2006];
13
+}
14
+//非静态模式下,不显示 2004016 HTML生成
15
+$seo_pseudo = empty($globalConfig['seo_pseudo']) ? 0 : $globalConfig['seo_pseudo'];
16
+if (empty($seo_pseudo) || $seo_pseudo != 2){
17
+    $other_rele_menu[] = 2004016;
18
+}
19
+//关闭回收站,不显示回收站入口
20
+$web_recycle_switch = empty($globalConfig['web_recycle_switch']) ? 0 : $globalConfig['web_recycle_switch'];
21
+if (!empty($web_recycle_switch) && $web_recycle_switch == 1){
22
+    $other_rele_menu[] = 2004006;
23
+}
24
+//关闭插件功能,全部插件入口屏蔽
25
+$web_weapp_switch = empty($globalConfig['web_weapp_switch']) ? 0 : $globalConfig['web_weapp_switch'];
26
+$module_rele_menu_web_weapp_switch = [2005];
27
+if (1 != $web_weapp_switch){
28
+    $menu_id_arr = M("admin_menu")->where(['controller_name'=>'Weapp'])->getField("menu_id",true);
29
+    if (!empty($menu_id_arr)){
30
+        $module_rele_menu_web_weapp_switch = array_merge($module_rele_menu_web_weapp_switch,$menu_id_arr);
31
+    }
32
+}
33
+//2006004 - 文章订单 --  会员中心与开启文章付费都开启才出来
34
+//$channeltype_list  = M("channeltype")->where(['id'=>['in',[1,5]]])->getField("id,data,status");
35
+//if (!empty($channeltype_list[1]['data'])){
36
+//    $data = json_decode($channeltype_list[1]['data'], true);
37
+//    if (empty($data['is_article_pay'])){
38
+//        $other_rele_menu[] = 2006004;
39
+//    }
40
+//}else{
41
+//    $other_rele_menu[] = 2006004;
42
+//}
43
+//"视频订单"  2006002  会员中心与视频模型启用才出来
44
+//if (empty($channeltype_list[5]['status'])){
45
+//    $other_rele_menu[] = 2006002;
46
+//}
47
+
48
+// 商城中心关联
49
+$shop_open_com = [2008,2008001,2008004,2008003,2008002,2008005,2008006,2008008];
50
+
51
+return array(
52
+    'module_rele_menu' => [    //模块开关控制入口导航,模块开启后,里面关联的开关才会打开
53
+        'web_users_switch' => [2006],  //会员中心
54
+//        'level_member_upgrade' => [],    //会员升级
55
+        'shop_open' =>  array_merge($shop_open_com, [2004021]),    //开启商城中心
56
+        'shop_open-close' =>  $shop_open_com,    //关闭商城中心
57
+        'web_weapp_switch' => $module_rele_menu_web_weapp_switch,     //插件应用
58
+        'pay_open' => [2004021],  //支付功能
59
+        'web_citysite_open' => [2004019],  //多城市站点
60
+    ],
61
+    'other_rele_menu' => $other_rele_menu,  //其他因素影响入口导航
62
+    'module_default_menu' => [     //模块默认关联入口(打开模块,无论原来的入口是否打开,都需要进入到打开状态)
63
+        'web_users_switch' => [2006],   //会员中心
64
+        'shop_open' =>  [2008], //[2008001,2008002,2008003,2008004,2008005,2008008],    //商城中心
65
+        'web_weapp_switch' => [2005],   //插件应用
66
+        'pay_open' => [2004021],  //支付功能
67
+    ],
68
+    'module_reverse_menu' => [   //模块开关控制入口导航,模块关闭时,里面关联的开关才会打开(与module_rele_menu相反)
69
+        'web_citysite_open' => [2004016],  //多城市站点
70
+    ]
71
+);

+ 0
- 0
application/admin/conf/md5list2.txt View File


+ 1268
- 0
application/admin/conf/menu.php
File diff suppressed because it is too large
View File


+ 5
- 0
application/admin/conf/session_conf.php View File

@@ -0,0 +1,5 @@
1
+<?php
2
+$session_1600593464 = json_encode(array (
3
+  'expire' => '7200',
4
+));
5
+define('EY_SESSION_CONF', $session_1600593464);

+ 100
- 0
application/admin/config.php View File

@@ -0,0 +1,100 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+$admin_ey_config = [
15
+    'seo_pseudo'    => 1, // 默认纯动态URL模式,兼容不支持pathinfo环境
16
+    'seo_dynamic_format'    => 1, // 1=兼容模式的URL,2=伪动态
17
+    'seo_rewrite_format'    => config('ey_config.seo_rewrite_format'),
18
+    'system_sql_mode'   => config('ey_config.system_sql_mode'), // 数据库模式
19
+    'seo_inlet' => config('ey_config.seo_inlet'), // 0=保留入口文件,1=隐藏入口文件
20
+];
21
+$ey_config = array_merge(config('ey_config'), $admin_ey_config);
22
+
23
+// 分页数
24
+$system_paginate_pagesize = input('param.pagesize/d', 0);
25
+if (empty($system_paginate_pagesize)) {
26
+    $system_paginate_pagesize = config('tpcache.system_paginate_pagesize');
27
+    $system_paginate_pagesize = !empty($system_paginate_pagesize) ? intval($system_paginate_pagesize) : 20;
28
+}
29
+
30
+$admin_config = array(
31
+    'ey_config' => $ey_config,
32
+    //分页配置
33
+    'paginate'      => array(
34
+        'list_rows' => $system_paginate_pagesize,
35
+    ),
36
+    // 默认全局过滤方法 用逗号分隔多个
37
+    'default_filter'         => 'htmlspecialchars',
38
+    // 登录有效期,单位秒
39
+    'login_expire' => 3600,
40
+    // 登录错误最大次数
41
+    'login_errtotal'   => 5,
42
+    // 登录错误超过次数之后,锁定用户名有效时间,单位秒
43
+    'login_errexpire'   => 600,
44
+    // +----------------------------------------------------------------------
45
+    // | 模板设置
46
+    // +----------------------------------------------------------------------
47
+    // 默认成功跳转对应的模板文件
48
+    'dispatch_success_tmpl'  => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
49
+    // 默认错误跳转对应的模板文件
50
+    'dispatch_error_tmpl'    => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
51
+
52
+    // +----------------------------------------------------------------------
53
+    // | 异常及错误设置
54
+    // +----------------------------------------------------------------------
55
+
56
+    // 异常页面的模板文件 
57
+    //'exception_tmpl'         => ROOT_PATH.'public/errpage/404.html',
58
+    // errorpage 错误页面
59
+    //'error_tmpl'         => ROOT_PATH.'public/errpage/404.html',
60
+
61
+    /**假设这个访问地址是 www.xxxxx.dev/home/goods/goodsInfo/id/1.html 
62
+     *就保存名字为 home_goods_goodsinfo_1.html     
63
+     *配置成这样, 指定 模块 控制器 方法名 参数名
64
+     */
65
+    'HTML_CACHE_STATUS' => false,
66
+    
67
+    // 控制器与操作名之间的连接符
68
+    'POWER_OPERATOR' => '@',
69
+
70
+    // 数据管理
71
+    'DATA_BACKUP_PATH' => '/data/sqldata', //数据库备份根路径
72
+    'DATA_BACKUP_PART_SIZE' => 524288000, //数据库备份卷大小 50M
73
+    'DATA_BACKUP_COMPRESS' => 0, //数据库备份文件是否启用压缩
74
+    'DATA_BACKUP_COMPRESS_LEVEL' => 9, //数据库备份文件压缩级别
75
+
76
+    // 过滤不需要登录的操作
77
+    'filter_login_action' => array(
78
+        'Admin@login',
79
+        'Admin@logout',
80
+        'Admin@vertify',
81
+        'Admin@wechat_login', // 扫码微信应用登录
82
+        'Admin@wechat_callback', // 扫码微信应用回调
83
+        'Admin@mp_getqrcode', // 获取微信公众号二维码
84
+        'Admin@mp_bingwxgzhopenid', // 绑定微信公众号二维码
85
+    ),
86
+    
87
+    // 无需验证权限的操作
88
+    'uneed_check_action' => array(
89
+        'Base@*',
90
+        'Index@*',
91
+        'Ajax@*',
92
+        'Ueditor@*',
93
+        'Uploadify@*',
94
+        'Uploadimgnew@*',
95
+    ),
96
+);
97
+
98
+$html_config = include_once 'html.php';
99
+return array_merge($admin_config, $html_config);
100
+?>

+ 842
- 0
application/admin/controller/AdPosition.php View File

@@ -0,0 +1,842 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Cache;
19
+
20
+class AdPosition extends Base
21
+{
22
+    private $ad_position_system_id = array(); // 系统默认位置ID,不可删除
23
+
24
+    public function _initialize() {
25
+        parent::_initialize();
26
+    }
27
+
28
+    public function index()
29
+    {
30
+        $list = array();
31
+        $get = input('get.');
32
+        $keywords = input('keywords/s');
33
+        $condition = [];
34
+        // 应用搜索条件
35
+        foreach (['keywords', 'type'] as $key) {
36
+            $get[$key] = addslashes(trim($get[$key]));
37
+            if (isset($get[$key]) && $get[$key] !== '') {
38
+                if ($key == 'keywords') {
39
+                    $condition['a.title'] = array('LIKE', "%{$get[$key]}%");
40
+                } else {
41
+                    $tmp_key = 'a.'.$key;
42
+                    $condition[$tmp_key] = array('eq', $get[$key]);
43
+                }
44
+            }
45
+        }
46
+
47
+        // 多语言
48
+        $condition['a.lang'] = array('eq', $this->admin_lang);
49
+
50
+        $adPositionM =  Db::name('ad_position');
51
+        $count = $adPositionM->alias('a')->where($condition)->count();// 查询满足要求的总记录数
52
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
53
+        $list = $adPositionM->alias('a')->where($condition)->order('id desc')->limit($Page->firstRow.','.$Page->listRows)->getAllWithIndex('id');
54
+
55
+        // 每组获取三张图片
56
+        $pids = get_arr_column($list, 'id');
57
+        $ad = Db::name('ad')->where(['pid' => ['IN', $pids], 'lang' => $this->admin_lang])->order('pid asc, id asc')->select();
58
+        foreach ($list as $k => $v) {
59
+            if (1 == $v['type']) {
60
+                // 图片封面图片
61
+                $v['ad'] = [];
62
+                foreach ($ad as $m => $n) {
63
+                    if ($v['id'] == $n['pid']) {
64
+                        $n['litpic'] = get_default_pic($n['litpic']); // 支持子目录
65
+                        $v['ad'][] = $n;
66
+                        unset($ad[$m]);
67
+                    } else {
68
+                        continue;
69
+                    }
70
+                }
71
+                // 若没有内容则显示默认图片
72
+                if (empty($v['ad'])) {
73
+                    $v['ad_count'] = 0;
74
+                    $v['ad'][]['litpic'] = ROOT_DIR . '/public/static/common/images/not_adv.jpg';
75
+                } else {
76
+                    $v['ad_count'] = count($v['ad']);
77
+                }
78
+                // 广告类型
79
+                $v['type_name'] = '图片';
80
+            } else if (2 == $v['type']) {
81
+                // 多媒体封面图片
82
+                $v['ad'][]['litpic'] = ROOT_DIR . '/public/static/admin/images/ad_type_media.png';
83
+                // 广告类型
84
+                $v['type_name'] = '多媒体';
85
+            } else if (3 == $v['type']) {
86
+                // HTML代码封面图片
87
+                $v['ad'][]['litpic'] = ROOT_DIR . '/public/static/admin/images/ad_type_html.png';
88
+                // 广告类型
89
+                $v['type_name'] = 'HTML代码';
90
+            }
91
+            $list[$k] = $v;
92
+        }
93
+
94
+        $show = $Page->show();// 分页显示输出
95
+        $this->assign('page',$show);// 赋值分页输出
96
+        $this->assign('list',$list);// 赋值数据集
97
+        $this->assign('pager',$Page);// 赋值分页对象
98
+
99
+        /*多语言模式下,广告位ID显示主体语言的ID和属性title名称*/
100
+        $main_adv_list = [];
101
+        if ($this->admin_lang != $this->main_lang && empty($this->globalConfig['language_split'])) {
102
+            $attr_values = get_arr_column($list, 'id');
103
+            $languageAttrRow = Db::name('language_attr')->field('attr_name,attr_value')->where([
104
+                    'attr_value'    => ['IN', $attr_values],
105
+                    'attr_group'    => 'ad_position',
106
+                    'lang'          => $this->admin_lang,
107
+                ])->getAllWithIndex('attr_value');
108
+            $ids = [];
109
+            foreach ($languageAttrRow as $key => $val) {
110
+                $tid_tmp = str_replace('adp', '', $val['attr_name']);
111
+                array_push($ids, intval($tid_tmp));
112
+            }
113
+            $main_advRow = Db::name('ad_position')->field("id,title,CONCAT('adp', id) AS attr_name")
114
+                ->where([
115
+                    'id'    => ['IN', $ids],
116
+                    'lang'  => $this->main_lang,
117
+                ])->getAllWithIndex('attr_name');
118
+            foreach ($list as $key => $val) {
119
+                $key_tmp = !empty($languageAttrRow[$val['id']]['attr_name']) ? $languageAttrRow[$val['id']]['attr_name'] : '';
120
+                $main_adv_list[$val['id']] = [
121
+                    'id'        => !empty($main_advRow[$key_tmp]['id']) ? $main_advRow[$key_tmp]['id'] : '',
122
+                    'title'  => !empty($main_advRow[$key_tmp]['title']) ? $main_advRow[$key_tmp]['title'] : '',
123
+                ];
124
+            }
125
+        }
126
+        $this->assign('main_adv_list', $main_adv_list);
127
+        /*end*/
128
+
129
+        return $this->fetch();
130
+    }
131
+    
132
+    /**
133
+     * 新增
134
+     */
135
+    public function add()
136
+    {
137
+        //防止php超时
138
+        function_exists('set_time_limit') && set_time_limit(0);
139
+
140
+        if (is_language() && empty($this->globalConfig['language_split'])) {
141
+            $this->language_access(); // 多语言功能操作权限
142
+        }
143
+
144
+        if (IS_POST) {
145
+            $post = input('post.');
146
+            $map = array(
147
+                'title' => trim($post['title']),
148
+                'lang'  => $this->admin_lang,
149
+            );
150
+            if(Db::name('ad_position')->where($map)->count() > 0){
151
+                $this->error('该广告名称已存在,请检查', url('AdPosition/index'));
152
+            }
153
+
154
+            // 添加广告位置表信息
155
+            $data = array(
156
+                'title'       => trim($post['title']),
157
+                'type'        => $post['type'],
158
+                'intro'       => $post['intro'],
159
+                'admin_id'    => session('admin_id'),
160
+                'lang'        => $this->admin_lang,
161
+                'add_time'    => getTime(),
162
+                'update_time' => getTime(),
163
+            );
164
+            $insertID = Db::name('ad_position')->insertGetId($data);
165
+
166
+            if (!empty($insertID)) {
167
+                // 同步广告位置ID到多语言的模板变量里,添加多语言广告位
168
+                $this->syn_add_language_attribute($insertID);
169
+
170
+                // 读取组合广告位的图片及信息
171
+                $AdData = [];
172
+                if (1 == $post['type'] && !empty($post['img_litpic'])) { // 图片类型
173
+                    $i = 1;
174
+                    foreach ($post['img_litpic'] as $key => $value) {
175
+                        if (!empty($value)) {
176
+                            // 去掉http:
177
+                            $value = str_replace("http:", "", $value);
178
+                            // 去掉https:
179
+                            $value = str_replace("https:", "", $value);
180
+                            // 主要参数
181
+                            $AdData['litpic'] = $value;
182
+                            $AdData['pid']    = $insertID;
183
+                            $AdData['title']  = trim($post['img_title'][$key]);
184
+                            $AdData['links']  = $post['img_links'][$key];
185
+                            $AdData['intro']  = $post['img_intro'][$key];
186
+                            $target = !empty($post['img_target'][$key]) ? 1 : 0;
187
+                            $AdData['target'] = $target;
188
+                            // 其他参数
189
+                            $AdData['media_type']  = 1;
190
+                            $AdData['admin_id']    = session('admin_id');
191
+                            $AdData['lang']        = $this->admin_lang;
192
+                            $AdData['sort_order']  = $i++;
193
+                            $AdData['add_time']    = getTime();
194
+                            $AdData['update_time'] = getTime();
195
+                            // 添加到广告图表
196
+                            $ad_id = Db::name('ad')->add($AdData);
197
+                            // 同步多语言
198
+                            $this->syn_add_ad_language_attribute($ad_id);
199
+                        }
200
+                    }
201
+
202
+                } else if (2 == $post['type'] && !empty($post['video_litpic'])) { // 媒体类型
203
+                    // 去掉http:
204
+                    $video_litpic = str_replace("http:", "", $post['video_litpic']);
205
+                    // 去掉https:
206
+                    $video_litpic = str_replace("https:", "", $post['video_litpic']);
207
+                    // 主要参数
208
+                    $AdData['litpic'] = $video_litpic;
209
+                    $AdData['pid']    = $insertID;
210
+                    $AdData['title']  = trim($post['title']);
211
+                    // 其他参数
212
+                    $AdData['intro']       = '';
213
+                    $AdData['links']       = '';
214
+                    $AdData['target']      = 0;
215
+                    $AdData['media_type']  = 2;
216
+                    $AdData['admin_id']    = session('admin_id');
217
+                    $AdData['lang']        = $this->admin_lang;
218
+                    $AdData['sort_order']  = 1;
219
+                    $AdData['add_time']    = getTime();
220
+                    $AdData['update_time'] = getTime();
221
+                    // 添加到广告图表
222
+                    $ad_id = Db::name('ad')->add($AdData);
223
+                    // 同步多语言
224
+                    $this->syn_add_ad_language_attribute($ad_id);
225
+
226
+                } else if (3 == $post['type'] && !empty($post['html_intro'])) { // HTML代码
227
+                    // 主要参数
228
+                    $AdData['pid']   = $insertID;
229
+                    $AdData['title'] = trim($post['title']);
230
+                    $AdData['intro'] = $post['html_intro'];
231
+                    // 其他参数
232
+                    $AdData['litpic']      = '';
233
+                    $AdData['links']       = '';
234
+                    $AdData['target']      = 0;
235
+                    $AdData['media_type']  = 3;
236
+                    $AdData['admin_id']    = session('admin_id');
237
+                    $AdData['lang']        = $this->admin_lang;
238
+                    $AdData['sort_order']  = 1;
239
+                    $AdData['add_time']    = getTime();
240
+                    $AdData['update_time'] = getTime();
241
+                    // 添加到广告图表
242
+                    $ad_id = Db::name('ad')->add($AdData);
243
+                    // 同步多语言
244
+                    $this->syn_add_ad_language_attribute($ad_id);
245
+
246
+                }
247
+                Cache::clear('ad');
248
+                adminLog('新增广告:'.$post['title']);
249
+                $this->success("操作成功", url('AdPosition/index'));
250
+            } else {
251
+                $this->error("操作失败", url('AdPosition/index'));
252
+            }
253
+        }
254
+
255
+        // 上传通道
256
+        $WeappConfig = Db::name('weapp')->field('code, status')->where('code', 'IN', ['Qiniuyun', 'AliyunOss', 'Cos'])->select();
257
+        $WeappOpen = [];
258
+        foreach ($WeappConfig as $value) {
259
+            if ('Qiniuyun' == $value['code']) {
260
+                $WeappOpen['qny_open'] = $value['status'];
261
+            } else if ('AliyunOss' == $value['code']) {
262
+                $WeappOpen['oss_open'] = $value['status'];
263
+            } else if ('Cos' == $value['code']) {
264
+                $WeappOpen['cos_open'] = $value['status'];
265
+            }
266
+        }
267
+        $this->assign('WeappOpen', $WeappOpen);
268
+
269
+        // 系统最大上传视频的大小
270
+        $upload_max_filesize = upload_max_filesize();
271
+        $this->assign('upload_max_filesize', $upload_max_filesize);
272
+
273
+        // 视频类型
274
+        $media_type = tpCache('global.media_type');
275
+        $media_type = !empty($media_type) ? $media_type : config('global.media_ext');
276
+        $media_type = str_replace(",", "|", $media_type);
277
+        $this->assign('media_type', $media_type);
278
+
279
+        return $this->fetch();
280
+    }
281
+
282
+    
283
+    /**
284
+     * 编辑
285
+     */
286
+    public function edit()
287
+    {
288
+        if (IS_POST) {
289
+            $post = input('post.');
290
+            if (!empty($post['id'])) {
291
+                $post['id'] = intval($post['id']);
292
+                if (array_key_exists($post['id'], $this->ad_position_system_id)) {
293
+                    $this->error("不可更改系统预定义位置", url('AdPosition/edit',array('id'=>$post['id'])));
294
+                }
295
+
296
+                /* 判断除自身外是否还有相同广告名称已存在 */
297
+                $map = array(
298
+                    'id'    => array('NEQ', $post['id']),
299
+                    'title' => trim($post['title']),
300
+                    'lang'  => $this->admin_lang,
301
+                );
302
+                if (Db::name('ad_position')->where($map)->count() > 0) $this->error('该广告名称已存在,请检查');
303
+                /* END */
304
+
305
+                /* 判断广告是否切换广告类型 */
306
+                // $where = [
307
+                //     'id'   => $post['id'],
308
+                //     'type' => $post['type'],
309
+                //     'lang' => $this->admin_lang
310
+                // ];
311
+                // if (Db::name('ad_position')->where($where)->count() == 0) {
312
+                //     // 已切换广告类型,清除广告中的广告内容
313
+                //     $where = [
314
+                //         'pid'  => $post['id'],
315
+                //         'lang' => $this->admin_lang
316
+                //     ];
317
+                //     Db::name('ad')->where($where)->delete();
318
+                // }
319
+                /* END */
320
+
321
+                /* 修改广告主体信息 */
322
+                $data = array(
323
+                    'id'          => $post['id'],
324
+                    'title'       => trim($post['title']),
325
+                    'type'        => $post['type'],
326
+                    'intro'       => $post['intro'],
327
+                    'update_time' => getTime(),
328
+                );
329
+                $resultID = Db::name('ad_position')->update($data);
330
+                /* END */
331
+            }
332
+
333
+            if (!empty($resultID)) {
334
+                $ad_db = Db::name('ad');
335
+                if (1 == $post['type'] && !empty($post['img_litpic'])) { // 图片类型
336
+                    // 读取组合广告位的图片及信息
337
+                    $i = 1;
338
+                    foreach ($post['img_litpic'] as $key => $value) {
339
+                        if (!empty($value)) {
340
+                            // 去掉http:
341
+                            $value = str_replace("http:", "", $value);
342
+                            // 去掉https:
343
+                            $value = str_replace("https:", "", $value);
344
+                            // 是否新窗口打开
345
+                            $target = !empty($post['img_target'][$key]) ? 1 : 0;
346
+                            // 广告位ID,为空则表示添加
347
+                            $ad_id = $post['img_id'][$key];
348
+                            if (!empty($ad_id)) {
349
+                                // 查询更新条件
350
+                                $where = [
351
+                                    'id'   => $ad_id,
352
+                                    'lang' => $this->admin_lang,
353
+                                ];
354
+                                if ($ad_db->where($where)->count() > 0) {
355
+                                    // 主要参数
356
+                                    $AdData['litpic']      = $value;
357
+                                    $AdData['title']       = $post['img_title'][$key];
358
+                                    $AdData['links']       = $post['img_links'][$key];
359
+                                    $AdData['intro']       = $post['img_intro'][$key];
360
+                                    $AdData['target']      = $target;
361
+                                    // 其他参数
362
+                                    $AdData['sort_order']  = $i++;
363
+                                    $AdData['update_time'] = getTime();
364
+                                    // 更新,不需要同步多语言
365
+                                    $ad_db->where($where)->update($AdData);
366
+                                } else {
367
+                                    // 主要参数
368
+                                    $AdData['litpic']      = $value;
369
+                                    $AdData['pid']         = $post['id'];
370
+                                    $AdData['title']       = $post['img_title'][$key];
371
+                                    $AdData['links']       = $post['img_links'][$key];
372
+                                    $AdData['intro']       = $post['img_intro'][$key];
373
+                                    $AdData['target']      = $target;
374
+                                    // 其他参数
375
+                                    $AdData['media_type']  = 1;
376
+                                    $AdData['admin_id']    = session('admin_id');
377
+                                    $AdData['lang']        = $this->admin_lang;
378
+                                    $AdData['sort_order']  = $i++;
379
+                                    $AdData['add_time']    = getTime();
380
+                                    $AdData['update_time'] = getTime();
381
+                                    $ad_id = $ad_db->add($AdData);
382
+                                    // 同步多语言
383
+                                    $this->syn_add_ad_language_attribute($ad_id);
384
+                                }
385
+                            } else {
386
+                                // 主要参数
387
+                                $AdData['litpic']      = $value;
388
+                                $AdData['pid']         = $post['id'];
389
+                                $AdData['title']       = $post['img_title'][$key];
390
+                                $AdData['links']       = $post['img_links'][$key];
391
+                                $AdData['intro']       = $post['img_intro'][$key];
392
+                                $AdData['target']      = $target;
393
+                                // 其他参数
394
+                                $AdData['media_type']  = 1;
395
+                                $AdData['admin_id']    = session('admin_id');
396
+                                $AdData['lang']        = $this->admin_lang;
397
+                                $AdData['sort_order']  = $i++;
398
+                                $AdData['add_time']    = getTime();
399
+                                $AdData['update_time'] = getTime();
400
+                                $ad_id = $ad_db->add($AdData);
401
+                                // 同步多语言
402
+                                $this->syn_add_ad_language_attribute($ad_id);
403
+                            }
404
+                        }
405
+                    }
406
+
407
+                } else if (2 == $post['type'] && !empty($post['video_litpic'])) { // 媒体类型
408
+                    // 去掉http:
409
+                    $video_litpic = str_replace("http:", "", $post['video_litpic']);
410
+                    // 去掉https:
411
+                    $video_litpic = str_replace("https:", "", $post['video_litpic']);
412
+                    if (!empty($post['video_id'])) {
413
+                        // 更新广告内容
414
+                        $AdData['litpic']      = $video_litpic;
415
+                        $AdData['title']       = trim($post['title']);
416
+                        $AdData['media_type']  = 2;
417
+                        $AdData['update_time'] = getTime();
418
+                        $ad_db->where('id', $post['video_id'])->update($AdData);
419
+                    } else {
420
+                        // 新增广告内容
421
+                        $AdData['litpic']      = $video_litpic;
422
+                        $AdData['pid']         = $post['id'];
423
+                        $AdData['title']       = trim($post['title']);
424
+                        $AdData['links']       = '';
425
+                        $AdData['intro']       = '';
426
+                        $AdData['target']      = 0;
427
+                        $AdData['media_type']  = 2;
428
+                        $AdData['admin_id']    = session('admin_id');
429
+                        $AdData['lang']        = $this->admin_lang;
430
+                        $AdData['sort_order']  = 1;
431
+                        $AdData['add_time']    = getTime();
432
+                        $AdData['update_time'] = getTime();
433
+                        $ad_id = $ad_db->add($AdData);
434
+                        // 同步多语言
435
+                        $this->syn_add_ad_language_attribute($ad_id);
436
+                    }
437
+                    
438
+                } else if (3 == $post['type'] && !empty($post['html_intro'])) { // HTML代码
439
+                    if (!empty($post['html_id'])) {
440
+                        // 更新广告内容
441
+                        $AdData['title']       = trim($post['title']);
442
+                        $AdData['intro']       = $post['html_intro'];
443
+                        $AdData['media_type']  = 3;
444
+                        $AdData['update_time'] = getTime();
445
+                        $ad_db->where('id', $post['html_id'])->update($AdData);
446
+                    } else {
447
+                        // 新增广告内容
448
+                        $AdData['litpic']      = '';
449
+                        $AdData['pid']         = $post['id'];
450
+                        $AdData['title']       = trim($post['title']);
451
+                        $AdData['intro']       = $post['html_intro'];
452
+                        $AdData['links']       = '';
453
+                        $AdData['target']      = 0;
454
+                        $AdData['media_type']  = 3;
455
+                        $AdData['admin_id']    = session('admin_id');
456
+                        $AdData['lang']        = $this->admin_lang;
457
+                        $AdData['sort_order']  = 1;
458
+                        $AdData['add_time']    = getTime();
459
+                        $AdData['update_time'] = getTime();
460
+                        $ad_id = $ad_db->add($AdData);
461
+                        // 同步多语言
462
+                        $this->syn_add_ad_language_attribute($ad_id);
463
+                    }
464
+                    
465
+                }
466
+                Cache::clear('ad');
467
+                adminLog('编辑广告:'.$post['title']);
468
+                $this->success("操作成功", url('AdPosition/index'));
469
+            } else {
470
+                $this->error("操作失败");
471
+            }
472
+        }
473
+
474
+        $assign_data = array();
475
+
476
+        $id = input('id/d');
477
+        $field = Db::name('ad_position')->field('a.*')->alias('a')->where(array('a.id'=>$id))->find();
478
+        if (empty($field)) $this->error('广告不存在,请联系管理员!');
479
+        switch ($field['type']) {
480
+            case '1':
481
+                $field['type_name'] = '图片';
482
+                break;
483
+            case '2':
484
+                $field['type_name'] = '多媒体';
485
+                break;
486
+            case '3':
487
+                $field['type_name'] = 'HTML代码';
488
+                break;
489
+        }
490
+        $assign_data['field'] = $field;
491
+
492
+        // 广告
493
+        $ad_data = Db::name('ad')->where(array('pid'=>$field['id']))->order('sort_order asc')->select();
494
+        foreach ($ad_data as $key => $val) {
495
+            if (1 == $val['media_type']) {
496
+                $ad_data[$key]['litpic'] = get_default_pic($val['litpic']); // 支持子目录
497
+            }
498
+        }
499
+        $assign_data['ad_data'] = $ad_data;
500
+
501
+        // 上传通道
502
+        $WeappConfig = Db::name('weapp')->field('code, status')->where('code', 'IN', ['Qiniuyun', 'AliyunOss', 'Cos'])->select();
503
+        $WeappOpen = [];
504
+        foreach ($WeappConfig as $value) {
505
+            if ('Qiniuyun' == $value['code']) {
506
+                $WeappOpen['qny_open'] = $value['status'];
507
+            } else if ('AliyunOss' == $value['code']) {
508
+                $WeappOpen['oss_open'] = $value['status'];
509
+            } else if ('Cos' == $value['code']) {
510
+                $WeappOpen['cos_open'] = $value['status'];
511
+            }
512
+        }
513
+        $this->assign('WeappOpen', $WeappOpen);
514
+
515
+        // 系统最大上传视频的大小
516
+        $file_size  = tpCache('global.file_size');
517
+        $postsize   = @ini_get('file_uploads') ? ini_get('post_max_size') : -1;
518
+        $fileupload = @ini_get('file_uploads') ? ini_get('upload_max_filesize') : -1;
519
+        $min_size   = strval($file_size) < strval($postsize) ? $file_size : $postsize;
520
+        $min_size   = strval($min_size) < strval($fileupload) ? $min_size : $fileupload;
521
+        $upload_max_filesize = intval($min_size) * 1024 * 1024;
522
+        $assign_data['upload_max_filesize'] = $upload_max_filesize;
523
+
524
+        // 视频类型
525
+        $media_type = tpCache('global.media_type');
526
+        $media_type = !empty($media_type) ? $media_type : config('global.media_ext');
527
+        $media_type = str_replace(",", "|", $media_type);
528
+        $assign_data['media_type'] = $media_type;
529
+
530
+        $this->assign($assign_data);
531
+        return $this->fetch();
532
+    }
533
+
534
+    /**
535
+     * 删除广告图片
536
+     */
537
+    public function del_imgupload()
538
+    {
539
+        if (is_language() && empty($this->globalConfig['language_split'])) {
540
+            $this->language_access(); // 多语言功能操作权限
541
+        }
542
+
543
+        $id_arr = input('del_id/a');
544
+        $id_arr = eyIntval($id_arr);
545
+        if(IS_POST && !empty($id_arr)){
546
+            /*多语言*/
547
+            $attr_name_arr = [];
548
+            if (empty($this->globalConfig['language_split'])) {
549
+                foreach ($id_arr as $key => $val) {
550
+                    $attr_name_arr[] = 'ad'.$val;
551
+                }
552
+                if (is_language()) {
553
+                    $new_id_arr = Db::name('language_attr')->where([
554
+                            'attr_name'  => ['IN', $attr_name_arr],
555
+                            'attr_group'    => 'ad',
556
+                        ])->column('attr_value');
557
+                    !empty($new_id_arr) && $id_arr = $new_id_arr;
558
+                }
559
+            } else {
560
+                if (get_admin_lang() == get_main_lang()) {
561
+                    foreach ($id_arr as $key => $val) {
562
+                        $attr_name_arr[] = 'ad'.$val;
563
+                    }
564
+                }
565
+            }
566
+            /*--end*/
567
+
568
+            $r = Db::name('ad')->where([
569
+                    'id' => ['IN', $id_arr],
570
+                ])
571
+                ->delete();
572
+            if ($r !== false) {
573
+                /*多语言*/
574
+                if (!empty($attr_name_arr)) {
575
+                    Db::name('language_attr')->where([
576
+                            'attr_name' => ['IN', $attr_name_arr],
577
+                            'attr_group'    => 'ad',
578
+                        ])->delete();
579
+
580
+                    Db::name('language_attribute')->where([
581
+                            'attr_name' => ['IN', $attr_name_arr],
582
+                            'attr_group'    => 'ad',
583
+                        ])->delete();
584
+                }
585
+                /*--end*/
586
+                Cache::clear('ad');
587
+                adminLog('删除广告-id:'.implode(',', $id_arr));
588
+            }
589
+        }
590
+    }
591
+
592
+    /**
593
+     * 删除
594
+     */
595
+    public function del()
596
+    {
597
+        if (is_language() && empty($this->globalConfig['language_split'])) {
598
+            $this->language_access(); // 多语言功能操作权限
599
+        }
600
+
601
+        $id_arr = input('del_id/a');
602
+        $id_arr = eyIntval($id_arr);
603
+        if(IS_POST && !empty($id_arr)){
604
+            foreach ($id_arr as $key => $val) {
605
+                if(array_key_exists($val, $this->ad_position_system_id)){
606
+                    $this->error('系统预定义,不能删除');
607
+                }
608
+            }
609
+
610
+            /*多语言*/
611
+            $attr_name_arr = [];
612
+            foreach ($id_arr as $key => $val) {
613
+                $attr_name_arr[] = 'adp'.$val;
614
+            }
615
+            if (is_language() && empty($this->globalConfig['language_split'])) {
616
+                $new_id_arr = Db::name('language_attr')->where([
617
+                        'attr_name' => ['IN', $attr_name_arr],
618
+                        'attr_group'    => 'ad_position',
619
+                    ])->column('attr_value');
620
+                !empty($new_id_arr) && $id_arr = $new_id_arr;
621
+            }
622
+            /*--end*/
623
+            $r = Db::name('ad_position')->where('id','IN',$id_arr)->delete();
624
+            if ($r !== false) {
625
+
626
+                /*多语言*/
627
+                if (!empty($attr_name_arr)) {
628
+                    if (get_admin_lang() == get_main_lang()) {
629
+                        Db::name('language_attribute')->where([
630
+                                'attr_name' => ['IN', $attr_name_arr],
631
+                                'attr_group'    => 'ad_position',
632
+                            ])->delete();
633
+                    }
634
+                    if (empty($this->globalConfig['language_split'])) {
635
+                        Db::name('language_attr')->where([
636
+                                'attr_name' => ['IN', $attr_name_arr],
637
+                                'attr_group'    => 'ad_position',
638
+                            ])->delete();
639
+                    } else {
640
+                        Db::name('language_attr')->where([
641
+                                'attr_value' => ['IN', $id_arr],
642
+                                'attr_group'    => 'ad_position',
643
+                            ])->delete();
644
+                    }
645
+                }
646
+                /*--end*/
647
+
648
+                $ad_ids = Db::name('ad')->where(['pid'=>['IN', $id_arr]])->column('id');
649
+                $attr_name_arr = [];
650
+                foreach ($ad_ids as $key => $val) {
651
+                    $attr_name_arr[] = "ad{$val}";
652
+                }
653
+                $r1 = Db::name('ad')->where('pid','IN',$id_arr)->delete();
654
+                if ($r1 !== false) {
655
+                    /*多语言*/
656
+                    if (!empty($attr_name_arr)) {
657
+                        if (get_admin_lang() == get_main_lang()) {
658
+                            Db::name('language_attribute')->where([
659
+                                    'attr_name' => ['IN', $attr_name_arr],
660
+                                    'attr_group'    => 'ad',
661
+                                ])->delete();
662
+                        }
663
+                        if (empty($this->globalConfig['language_split'])) {
664
+                            Db::name('language_attr')->where([
665
+                                    'attr_name' => ['IN', $attr_name_arr],
666
+                                    'attr_group'    => 'ad',
667
+                                ])->delete();
668
+                        } else {
669
+                            Db::name('language_attr')->where([
670
+                                    'attr_value' => ['IN', $ad_ids],
671
+                                    'attr_group'    => 'ad',
672
+                                ])->delete();
673
+                        }
674
+                    }
675
+                    /*--end*/
676
+                }
677
+
678
+                Cache::clear('ad');
679
+                adminLog('删除广告-id:'.implode(',', $id_arr));
680
+                $this->success('删除成功');
681
+            } else {
682
+                $this->error('删除失败');
683
+            }
684
+        }else{
685
+            $this->error('参数有误');
686
+        }
687
+    }
688
+
689
+    /**
690
+     * 打开预览视频
691
+     */
692
+    public function open_preview_video()
693
+    {
694
+        $post = input('post.');
695
+        $video_litpic = $post['video_litpic'];
696
+        if (!is_http_url($video_litpic)) {
697
+            $video_litpic = request()->domain() . handle_subdir_pic($video_litpic, 'media');
698
+        }
699
+        $this->success('执行成功', $video_litpic);
700
+    }
701
+
702
+    /**
703
+     * 检测广告名称是否存在重复
704
+     */
705
+    public function detection_title_repeat()
706
+    {
707
+        if (IS_AJAX_POST) {
708
+            $post = input('post.');
709
+            $where = [
710
+                'id'    => ['NEQ', $post['id']],
711
+                'title' => trim($post['title']),
712
+                'lang'  => $this->admin_lang,
713
+            ];
714
+            $count = Db::name('ad_position')->where($where)->count();
715
+            if (empty($count)) {
716
+                $this->success('检测通过');
717
+            } else {
718
+                $this->error('该广告名称已存在,请检查');
719
+            }
720
+        }
721
+    }
722
+
723
+    /**
724
+     * 同步新增广告位置ID到多语言的模板变量里
725
+     */
726
+    private function syn_add_language_attribute($adp_id)
727
+    {
728
+        /*单语言情况下不执行多语言代码*/
729
+        if (!is_language() || tpCache('language.language_split')) {
730
+            return true;
731
+        }
732
+        /*--end*/
733
+
734
+        $attr_group = 'ad_position';
735
+        $admin_lang = $this->admin_lang;
736
+        $main_lang = $this->main_lang;
737
+        $languageRow = Db::name('language')->field('mark')->order('id asc')->select();
738
+        if (!empty($languageRow) && $admin_lang == $main_lang) { // 当前语言是主体语言,即语言列表最早新增的语言
739
+            $ad_position_db = Db::name('ad_position');
740
+            $result = $ad_position_db->find($adp_id);
741
+            $attr_name = 'adp'.$adp_id;
742
+            $r = Db::name('language_attribute')->save([
743
+                'attr_title'    => $result['title'],
744
+                'attr_name'     => $attr_name,
745
+                'attr_group'    => $attr_group,
746
+                'add_time'      => getTime(),
747
+                'update_time'   => getTime(),
748
+            ]);
749
+            if (false !== $r) {
750
+                $data = [];
751
+                foreach ($languageRow as $key => $val) {
752
+                    /*同步新广告位置到其他语言广告位置列表*/
753
+                    if ($val['mark'] != $admin_lang) {
754
+                        $addsaveData = $result;
755
+                        $addsaveData['lang']  = $val['mark'];
756
+                        $addsaveData['title'] = $val['mark'].$addsaveData['title'];
757
+                        unset($addsaveData['id']);
758
+                        $adp_id = $ad_position_db->insertGetId($addsaveData);
759
+                    }
760
+                    /*--end*/
761
+                    
762
+                    /*所有语言绑定在主语言的ID容器里*/
763
+                    $data[] = [
764
+                        'attr_name' => $attr_name,
765
+                        'attr_value'    => $adp_id,
766
+                        'lang'  => $val['mark'],
767
+                        'attr_group'    => $attr_group,
768
+                        'add_time'      => getTime(),
769
+                        'update_time'   => getTime(),
770
+                    ];
771
+                    /*--end*/
772
+                }
773
+                if (!empty($data)) {
774
+                    model('LanguageAttr')->saveAll($data);
775
+                }
776
+            }
777
+        }
778
+    }
779
+
780
+    /**
781
+     * 同步新增广告ID到多语言的模板变量里
782
+     */
783
+   private function syn_add_ad_language_attribute($ad_id)
784
+    {
785
+        /*单语言情况下不执行多语言代码*/
786
+        if (!is_language() || tpCache('language.language_split')) {
787
+            return true;
788
+        }
789
+        /*--end*/
790
+
791
+        $attr_group = 'ad';
792
+        $admin_lang = $this->admin_lang;
793
+        $main_lang = get_main_lang();
794
+        $languageRow = Db::name('language')->field('mark')->order('id asc')->select();
795
+        if (!empty($languageRow) && $admin_lang == $main_lang) { // 当前语言是主体语言,即语言列表最早新增的语言
796
+            $ad_db = Db::name('ad');
797
+            $result = $ad_db->find($ad_id);
798
+            $attr_name = 'ad'.$ad_id;
799
+            $r = Db::name('language_attribute')->save([
800
+                'attr_title'    => $result['title'],
801
+                'attr_name'     => $attr_name,
802
+                'attr_group'    => $attr_group,
803
+                'add_time'      => getTime(),
804
+                'update_time'   => getTime(),
805
+            ]);
806
+            if (false !== $r) {
807
+                $data = [];
808
+                foreach ($languageRow as $key => $val) {
809
+                    /*同步新广告到其他语言广告列表*/
810
+                    if ($val['mark'] != $admin_lang) {
811
+                        $addsaveData = $result;
812
+                        $addsaveData['lang'] = $val['mark'];
813
+                        $newPid = Db::name('language_attr')->where([
814
+                                'attr_name' => 'adp'.$result['pid'],
815
+                                'attr_group'    => 'ad_position',
816
+                                'lang'  => $val['mark'],
817
+                            ])->getField('attr_value');
818
+                        $addsaveData['pid']   = $newPid;
819
+                        $addsaveData['title'] = $val['mark'].$addsaveData['title'];
820
+                        unset($addsaveData['id']);
821
+                        $ad_id = $ad_db->insertGetId($addsaveData);
822
+                    }
823
+                    /*--end*/
824
+                    
825
+                    /*所有语言绑定在主语言的ID容器里*/
826
+                    $data[] = [
827
+                        'attr_name'   => $attr_name,
828
+                        'attr_value'  => $ad_id,
829
+                        'lang'        => $val['mark'],
830
+                        'attr_group'  => $attr_group,
831
+                        'add_time'    => getTime(),
832
+                        'update_time' => getTime(),
833
+                    ];
834
+                    /*--end*/
835
+                }
836
+                if (!empty($data)) {
837
+                    model('LanguageAttr')->saveAll($data);
838
+                }
839
+            }
840
+        }
841
+    }
842
+}

+ 1547
- 0
application/admin/controller/Admin.php
File diff suppressed because it is too large
View File


+ 324
- 0
application/admin/controller/Ajax.php View File

@@ -0,0 +1,324 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use think\Db;
16
+use think\Session;
17
+use think\Config;
18
+use app\admin\logic\AjaxLogic;
19
+
20
+/**
21
+ * 所有ajax请求或者不经过权限验证的方法全放在这里
22
+ */
23
+class Ajax extends Base {
24
+    
25
+    private $ajaxLogic;
26
+
27
+    public function _initialize() {
28
+        parent::_initialize();
29
+        $this->ajaxLogic = new AjaxLogic;
30
+    }
31
+
32
+    /*
33
+     * 移动重新排序
34
+     */
35
+    public function ajax_move_admin_menu(){
36
+        $post = input("post.");
37
+        $menu_id_arr = $post['menu_id'];
38
+        try{
39
+            foreach ($menu_id_arr as $key=>$val){
40
+                if ($val != 2004){
41
+                    Db::name("admin_menu")->where(['menu_id'=>$val])->setField('sort_order',$key);
42
+                }
43
+            }
44
+        }catch (\Exception $e){
45
+            die("修改失败");
46
+        }
47
+        $this->success("移动排序成功");
48
+    }
49
+    /*
50
+     *  添加、删除左侧菜单栏目
51
+     */
52
+    public function update_admin_menu(){
53
+        if (IS_AJAX_POST) {
54
+            $post = input('post.');
55
+            if (empty($post['title']) || empty($post['controller_name']) || empty($post['action_name']) || empty($post['menu_id']) || empty($post['type'])){
56
+                $this->error('请传入正确参数');
57
+            }
58
+            $menu_info = Db::name("admin_menu")->where(['menu_id'=>$post['menu_id']])->find();
59
+            $icon = !empty($post['icon']) ? $post['icon'] : 'fa fa-minus';
60
+            if ($post['type'] == 1){   //添加目录
61
+                if (!empty($post['target'])) {
62
+                    $target = $post['target'];
63
+                } else {
64
+                    $all_menu_tree = getAllMenu();
65
+                    $all_menu_list = tree_to_list($all_menu_tree,'child','id');
66
+                    $target = empty($all_menu_list[$post['menu_id']]['target']) ? 'workspace' : $all_menu_list[$post['menu_id']]['target'];
67
+                }
68
+                $is_switch = isset($post['is_switch']) ? $post['is_switch'] : 1;
69
+                if (!empty($menu_info)){
70
+                    $update_data = ['icon' => $icon,'is_menu'=>1, 'is_switch' => $is_switch,'sort_order'=>100,'update_time' => getTime()];
71
+                    if(!empty($post['controller_name'])){
72
+                        $update_data['controller_name'] = $post['controller_name'];
73
+                    }
74
+                    if(!empty($post['action_name'])){
75
+                        $update_data['action_name'] = $post['action_name'];
76
+                    }
77
+                    if(!empty($post['param'])){
78
+                        $update_data['param'] = $post['param'];
79
+                    }
80
+                    if(!empty($target)){
81
+                        $update_data['target'] = $target;
82
+                    }
83
+                    $r = Db::name("admin_menu")->where(['menu_id'=>$menu_info['menu_id']])->update($update_data);
84
+                }else{
85
+                    $menu_info = [
86
+                        'menu_id' => $post['menu_id'],
87
+                        'title' => $post['title'],
88
+                        'controller_name' => $post['controller_name'],
89
+                        'action_name' => $post['action_name'],
90
+                        'param' => !empty($post['param']) ? $post['param'] : '',
91
+                        'icon' => $icon,
92
+                        'is_menu' => 1,
93
+                        'is_switch' => $is_switch,
94
+                        'target' => $target,
95
+                        'add_time' => getTime(),
96
+                        'update_time' => getTime()
97
+                    ];
98
+                    Db::name("admin_menu")->where([ 'title' => $post['title'], 'controller_name' => $post['controller_name'],'action_name' => $post['action_name']])->delete();
99
+                    $r = Db::name("admin_menu")->insert($menu_info);
100
+                }
101
+                if ($r !== false) {
102
+                    $menu_info['url'] = url($post['controller_name']."/".$post['action_name']);
103
+                    $this->success("添加成功",null,$menu_info);
104
+                }
105
+            }else{          //删除目录
106
+                if (!empty($menu_info)){
107
+                    $r = Db::name("admin_menu")->where(['menu_id'=>$menu_info['menu_id']])->update(['is_menu'=>0,'sort_order'=>100,'update_time' => getTime()]);
108
+                    if ($r !== false) {
109
+                        $this->success("删除成功");
110
+                    }
111
+                }
112
+            }
113
+        }
114
+
115
+        $this->error('请求错误');
116
+    }
117
+    /**
118
+     * 进入欢迎页面需要异步处理的业务
119
+     */
120
+    public function welcome_handle()
121
+    {
122
+        \think\Session::pause(); // 暂停session,防止session阻塞机制
123
+        $this->ajaxLogic->welcome_handle();
124
+    }
125
+
126
+    /**
127
+     * 隐藏后台欢迎页的系统提示
128
+     */
129
+    public function explanation_welcome()
130
+    {
131
+        \think\Session::pause(); // 暂停session,防止session阻塞机制
132
+        $type = input('param.type/d', 0);
133
+        $tpCacheKey = 'system_explanation_welcome';
134
+        if (1 < $type) {
135
+            $tpCacheKey .= '_'.$type;
136
+        }
137
+        
138
+        /*多语言*/
139
+        if (is_language()) {
140
+            $langRow = \think\Db::name('language')->field('mark')->order('id asc')->select();
141
+            foreach ($langRow as $key => $val) {
142
+                tpCache('system', [$tpCacheKey=>1], $val['mark']);
143
+            }
144
+        } else { // 单语言
145
+            tpCache('system', [$tpCacheKey=>1]);
146
+        }
147
+        /*--end*/
148
+    }
149
+
150
+    /**
151
+     * 版本检测更新弹窗
152
+     */
153
+    public function check_upgrade_version()
154
+    {
155
+        \think\Session::pause(); // 暂停session,防止session阻塞机制
156
+        $upgradeLogic = new \app\admin\logic\UpgradeLogic;
157
+        $security_patch = tpSetting('upgrade.upgrade_security_patch');
158
+        if (!empty($security_patch) && 1 == $security_patch) {
159
+            $upgradeMsg = $upgradeLogic->checkSecurityVersion(); // 安全补丁包消息
160
+        } else {
161
+            $upgradeMsg = $upgradeLogic->checkVersion(); // 升级包消息
162
+        }
163
+
164
+        // 权限控制 by 小虎哥
165
+        $admin_info = session('admin_info');
166
+        if (0 < intval($admin_info['role_id'])) {
167
+            $auth_role_info = $admin_info['auth_role_info'];
168
+            if (isset($auth_role_info['online_update']) && 1 != $auth_role_info['online_update']) {
169
+                $upgradeMsg = ['code' => 1, 'msg' => '已是最新版'];
170
+            }
171
+        }
172
+
173
+        $this->success('检测成功', null, $upgradeMsg);  
174
+    }
175
+
176
+    /**
177
+     * 更新stiemap.xml地图
178
+     */
179
+    public function update_sitemap($controller, $action)
180
+    {
181
+        if (IS_AJAX_POST) {
182
+            \think\Session::pause(); // 暂停session,防止session阻塞机制
183
+            $channeltype_row = \think\Cache::get("extra_global_channeltype");
184
+            if (empty($channeltype_row)) {
185
+                $ctlArr = \think\Db::name('channeltype')
186
+                    ->where('id','NOTIN', [6,8])
187
+                    ->column('ctl_name');
188
+            } else {
189
+                $ctlArr = array();
190
+                foreach($channeltype_row as $key => $val){
191
+                    if (!in_array($val['id'], [6,8])) {
192
+                        $ctlArr[] = $val['ctl_name'];
193
+                    }
194
+                }
195
+            }
196
+
197
+            $systemCtl= ['Arctype','Archives'];
198
+            $ctlArr = array_merge($systemCtl, $ctlArr);
199
+            $actArr = ['add','edit','del'];
200
+            if (in_array($controller, $ctlArr) && in_array($action, $actArr)) {
201
+                Session::pause(); // 暂停session,防止session阻塞机制
202
+                sitemap_auto();
203
+                $this->success('更新sitemap成功!');
204
+            }
205
+        }
206
+
207
+        $this->error('更新sitemap失败!');
208
+    }
209
+
210
+    // 开启\关闭余额支付
211
+    public function BalancePayOpen()
212
+    {
213
+        if (IS_AJAX_POST) {
214
+            $open_value = input('post.open_value/d');
215
+            getUsersConfigData('pay', ['pay_balance_open' => $open_value]);
216
+            $this->success('操作成功');
217
+        }
218
+    }
219
+
220
+    /**
221
+     * 跳转到前台内容页
222
+     * @return [type] [description]
223
+     */
224
+    public function toHomeView()
225
+    {
226
+        $aid = input('param.aid/d');
227
+        $archives = Db::name('archives')->alias('a')
228
+            ->field('b.*, a.*')
229
+            ->join('arctype b', 'a.typeid = b.id', 'LEFT')
230
+            ->where(['a.aid'=>$aid])
231
+            ->find();
232
+        if (!empty($archives)) {
233
+            if ($archives['arcrank'] >= 0) {
234
+                $url = get_arcurl($archives, false);
235
+            } else {
236
+                $url = get_arcurl($archives, true);
237
+            }
238
+            header('Location: '.$url);
239
+            exit;
240
+        } else {
241
+            to_index("404");
242
+        }
243
+    }
244
+
245
+    //处理多语言字段绑定兼容
246
+    public function repair_language_data()
247
+    {
248
+        $admin_logic_1692067658 = tpSetting('syn.admin_logic_1692067658', [], 'cn');
249
+        if (empty($admin_logic_1692067658)) {
250
+            //判断有没有除了中文以外的
251
+            $lang_count = Db::name('language')->where('mark','neq','cn')->count();
252
+            if (!empty($lang_count)) {
253
+                //有则执行兼容
254
+                $channeltypeRow = Db::name('archives')
255
+                    ->alias('a')
256
+                    ->join('channeltype b','a.channel = b.id','left')
257
+                    ->where(['a.lang' => 'cn', 'a.is_del' => 0, 'a.channel' => ['neq', 6]])
258
+                    ->group('channel')
259
+                    ->field('a.channel,b.id,b.nid,b.table')->getAllWithIndex('id');
260
+                if (!empty($channeltypeRow)) {
261
+                    $typeids_row = [];
262
+                    $row = Db::name('archives')->field('typeid,channel')->where(['lang' => 'cn', 'is_del' => 0])->group('typeid')->select();
263
+                    foreach ($row as $key => $val) {
264
+                        $typeids_row[$val['channel']][] = $val['typeid'];
265
+                    }
266
+                    foreach ($channeltypeRow as $k => $v) {
267
+                        $typeids = empty($typeids_row[$k]) ? [] : $typeids_row[$k];
268
+                        $typeids_arr = [];
269
+                        foreach ($typeids as $key => $val) {
270
+                            $typeids_arr[] = 'tid' . $val;
271
+                        }
272
+                        //查出对应的多语言栏目字段
273
+                        $lang_typeids = Db::name('language_attr')->where(['attr_group' => 'arctype', 'attr_name' => ['in', $typeids_arr], 'lang' => ['neq', 'cn']])->field('attr_value,attr_name')->getAllWithIndex('attr_name');
274
+                        //查询栏目绑定
275
+                        $channelfield_bind_row = Db::name('channelfield_bind')->field('*')->select();
276
+                        $new_arr = array();
277
+                        $bind_field_ids_arr = [];
278
+                        foreach ($channelfield_bind_row as $k => $v) {
279
+                            $new_arr[$v['typeid']][] = $v;
280
+                            $bind_field_ids_arr[$v['typeid']][] = $v['field_id'];
281
+                        }
282
+                        $channelfield_bind_row = $new_arr;
283
+                        foreach ($typeids as $key => $val) {
284
+                            // 中文栏目ID
285
+                            $typeid_old = $val;
286
+                            //多语言栏目id
287
+                            $typeid = $lang_typeids['tid' . $typeid_old]['attr_value'];
288
+
289
+                            //查询栏目绑定
290
+                            $channelfield_bind_list = empty($channelfield_bind_row[$typeid_old]) ? [] : $channelfield_bind_row[$typeid_old];
291
+                            if (!empty($channelfield_bind_list)) {
292
+                                $field_ids = get_arr_column($channelfield_bind_list, 'field_id');
293
+                                //查询已经写入的
294
+                                $bind_field_ids = [];
295
+                                if (!empty($bind_field_ids_arr[$typeid])) {
296
+                                    foreach ($bind_field_ids_arr[$typeid] as $_k1 => $_v1) {
297
+                                        if (in_array($_v1, $field_ids)) {
298
+                                            $bind_field_ids[] = $_v1;
299
+                                        }
300
+                                    }
301
+                                }
302
+                                $channelfield_bind_insert = [];
303
+                                foreach ($channelfield_bind_list as $k => $v) {
304
+                                    //已经写入的不在写入
305
+                                    if (!in_array($v['field_id'], $bind_field_ids)) {
306
+                                        $channelfield_bind_insert[] = [
307
+                                            'typeid' => $typeid,
308
+                                            'field_id' => $v['field_id'],
309
+                                            'add_time' => getTime(),
310
+                                            'update_time' => getTime()
311
+                                        ];
312
+                                    }
313
+                                }
314
+                                //写入绑定自定义字段
315
+                                !empty($channelfield_bind_insert) && Db::name('channelfield_bind')->insertAll($channelfield_bind_insert);
316
+                            }
317
+                        }
318
+                    }
319
+                }
320
+            }
321
+            tpSetting('syn', ['admin_logic_1692067658'=>1], 'cn');
322
+        }
323
+    }
324
+}

+ 1908
- 0
application/admin/controller/Archives.php
File diff suppressed because it is too large
View File


+ 44
- 0
application/admin/controller/ArchivesFlag.php View File

@@ -0,0 +1,44 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class ArchivesFlag extends Base
21
+{
22
+    public function index()
23
+    {
24
+        $list = array();
25
+        $keywords = input('keywords/s');
26
+        $keywords = addslashes(trim($keywords));
27
+
28
+        $condition = array();
29
+        if (!empty($keywords)) {
30
+            $condition['flag_name'] = array('LIKE', "%{$keywords}%");
31
+        }
32
+
33
+        $archivesflagM =  Db::name('archives_flag');
34
+        $count = $archivesflagM->where($condition)->count('id');// 查询满足要求的总记录数
35
+        $Page = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
36
+        $list = $archivesflagM->where($condition)->order('sort_order asc, id asc')->limit($Page->firstRow.','.$Page->listRows)->select();
37
+
38
+        $show = $Page->show();// 分页显示输出
39
+        $this->assign('page',$show);// 赋值分页输出
40
+        $this->assign('list',$list);// 赋值数据集
41
+        $this->assign('pager',$pager);// 赋值分页对象
42
+        return $this->fetch();
43
+    }
44
+}

+ 1649
- 0
application/admin/controller/Arctype.php
File diff suppressed because it is too large
View File


+ 930
- 0
application/admin/controller/Article.php View File

@@ -0,0 +1,930 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Config;
19
+
20
+class Article extends Base
21
+{
22
+    // 模型标识
23
+    public $nid = 'article';
24
+    // 模型ID
25
+    public $channeltype = '';
26
+
27
+    public function _initialize()
28
+    {
29
+        parent::_initialize();
30
+        $channeltype_list  = config('global.channeltype_list');
31
+        $this->channeltype = $channeltype_list[$this->nid];
32
+        empty($this->channeltype) && $this->channeltype = 1;
33
+        $this->assign('nid', $this->nid);
34
+        $this->assign('channeltype', $this->channeltype);
35
+
36
+        // 返回页面
37
+        $paramTypeid = input('param.typeid/d', 0);
38
+        $this->callback_url = url('Article/index', ['lang' => $this->admin_lang, 'typeid' => $paramTypeid]);
39
+        $this->assign('callback_url', $this->callback_url);
40
+    }
41
+
42
+    /**
43
+     * 文章列表
44
+     */
45
+    public function index()
46
+    {
47
+        $assign_data = $condition = [];
48
+
49
+        // 获取到所有GET参数
50
+        $param = input('param.');
51
+        $typeid = input('typeid/d', 0);
52
+
53
+        // 搜索、筛选查询条件处理
54
+        foreach (['keywords', 'typeid', 'flag', 'is_release','province_id','city_id','area_id'] as $key) {
55
+            if ($key == 'typeid' && empty($param['typeid'])) {
56
+                $typeids = Db::name('arctype')->where('current_channel', $this->channeltype)->column('id');
57
+                $condition['a.typeid'] = array('IN', $typeids);
58
+            }
59
+            $param[$key] = isset($param[$key]) ? addslashes(trim($param[$key])) : '';
60
+            if (isset($param[$key]) && $param[$key] !== '') {
61
+                if ($key == 'keywords') {
62
+                    $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
63
+                } else if ($key == 'typeid') {
64
+                    $typeid = $param[$key];
65
+                    $hasRow = model('Arctype')->getHasChildren($typeid);
66
+                    $typeids = get_arr_column($hasRow, 'id');
67
+                    // 权限控制 by 小虎哥
68
+                    $admin_info = session('admin_info');
69
+                    if (0 < intval($admin_info['role_id'])) {
70
+                        $auth_role_info = $admin_info['auth_role_info'];
71
+                        if (!empty($typeid) && !empty($auth_role_info) && !empty($auth_role_info['permission']['arctype'])) {
72
+                            $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
73
+                        }
74
+                    }
75
+                    $condition['a.typeid'] = array('IN', $typeids);
76
+                } else if ($key == 'flag') {
77
+                    if ('is_release' == $param[$key]) {
78
+                        $condition['a.users_id'] = array('gt', 0);
79
+                    } else {
80
+                        $FlagNew = $param[$key];
81
+                        $condition['a.'.$param[$key]] = array('eq', 1);
82
+                    }
83
+                } else if (in_array($key, ['province_id','city_id','area_id'])) {
84
+                    if (!empty($param['area_id'])) {
85
+                        $condition['a.area_id'] = $param['area_id'];
86
+                    } else if (!empty($param['city_id'])) {
87
+                        $condition['a.city_id'] = $param['city_id'];
88
+                    } else if (!empty($param['province_id'])) {
89
+                        $condition['a.province_id'] = $param['province_id'];
90
+                    }
91
+                } else {
92
+                    $condition['a.'.$key] = array('eq', $param[$key]);
93
+                }
94
+            }
95
+        }
96
+
97
+        // 权限控制 by 小虎哥
98
+        $admin_info = session('admin_info');
99
+        if (0 < intval($admin_info['role_id'])) {
100
+            $auth_role_info = $admin_info['auth_role_info'];
101
+            if (!empty($auth_role_info) && isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
102
+                $condition['a.admin_id'] = $admin_info['admin_id'];
103
+            }
104
+        }
105
+
106
+        // 时间检索条件
107
+        $begin = strtotime(input('add_time_begin'));
108
+        $end = strtotime(input('add_time_end'));
109
+        if ($begin > 0 && $end > 0) {
110
+            $condition['a.add_time'] = array('between', "$begin, $end");
111
+        } else if ($begin > 0) {
112
+            $condition['a.add_time'] = array('egt', $begin);
113
+        } else if ($end > 0) {
114
+            $condition['a.add_time'] = array('elt', $end);
115
+        }
116
+
117
+        // 必要条件
118
+        $condition['a.channel'] = array('eq', $this->channeltype);
119
+        $condition['a.lang'] = array('eq', $this->admin_lang);
120
+        $condition['a.is_del'] = array('eq', 0);
121
+        $condition['a.arcrank'] = array('egt', -1);
122
+        $conditionNew = "(a.users_id = 0 OR (a.users_id > 0 AND a.arcrank >= 0))";
123
+
124
+        // 自定义排序
125
+        $orderby = input('param.orderby/s');
126
+        $orderway = input('param.orderway/s');
127
+        if (!empty($orderby) && !empty($orderway)) {
128
+            $orderby = "a.{$orderby} {$orderway}, a.aid desc";
129
+        } else {
130
+            $orderby = "a.aid desc";
131
+        }
132
+
133
+        // 数据查询,搜索出主键ID的值
134
+        $SqlQuery = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->fetchSql()->count('aid');
135
+        $count = Db::name('sql_cache_table')->where(['sql_md5'=>md5($SqlQuery)])->getField('sql_result');
136
+        $count = ($count < 0) ? 0 : $count;
137
+        if (empty($count)) {
138
+            $count = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->count('aid');
139
+            /*添加查询执行语句到mysql缓存表*/
140
+            $SqlCacheTable = [
141
+                'sql_name' => '|article|' . $this->channeltype . '|',
142
+                'sql_result' => $count,
143
+                'sql_md5' => md5($SqlQuery),
144
+                'sql_query' => $SqlQuery,
145
+                'add_time' => getTime(),
146
+                'update_time' => getTime(),
147
+            ];
148
+            if (!empty($FlagNew)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $FlagNew . '|';
149
+            if (!empty($typeid)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $typeid . '|';
150
+            if (!empty($keywords)) $SqlCacheTable['sql_name'] = '|article|keywords|';
151
+            Db::name('sql_cache_table')->insertGetId($SqlCacheTable);
152
+            /*END*/
153
+        }
154
+
155
+        $Page = new Page($count, config('paginate.list_rows'));
156
+        $list = [];
157
+        if (!empty($count)) {
158
+            $limit = $count > config('paginate.list_rows') ? $Page->firstRow.','.$Page->listRows : $count;
159
+            $list = Db::name('archives')
160
+                ->field("a.aid")
161
+                ->alias('a')
162
+                ->where($condition)
163
+                ->where($conditionNew)
164
+                ->order($orderby)
165
+                ->limit($limit)
166
+                ->getAllWithIndex('aid');
167
+            // 在数据量大的情况下,经过优化的搜索逻辑,先搜索出主键ID,再通过ID将其他信息补充完整
168
+            if (!empty($list)) {
169
+                $aids = array_keys($list);
170
+                $fields = "b.*, a.*, a.aid as aid";
171
+                $row = Db::name('archives')
172
+                    ->field($fields)
173
+                    ->alias('a')
174
+                    ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
175
+                    ->where('a.aid', 'in', $aids)
176
+                    ->getAllWithIndex('aid');
177
+                foreach ($list as $key => $val) {
178
+                    $row[$val['aid']]['arcurl'] = get_arcurl($row[$val['aid']]);
179
+                    $row[$val['aid']]['litpic'] = handle_subdir_pic($row[$val['aid']]['litpic']);
180
+                    $list[$key] = $row[$val['aid']];
181
+                }
182
+            }
183
+        }
184
+        
185
+        $show = $Page->show();
186
+        $assign_data['page'] = $show;
187
+        $assign_data['list'] = $list;
188
+        $assign_data['pager'] = $Page;
189
+        $assign_data['typeid'] = $typeid;
190
+        $assign_data['tab'] = input('param.tab/d', 3);// 选项卡
191
+        $assign_data['seo_pseudo'] = tpCache('global.seo_pseudo');// 前台URL模式
192
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();// 文档属性
193
+        $assign_data['arctype_info'] = $typeid > 0 ? Db::name('arctype')->field('typename')->find($typeid) : [];// 当前栏目信息
194
+        $this->assign($assign_data);
195
+        return $this->fetch();
196
+    }
197
+
198
+    //添加
199
+    public function add()
200
+    {
201
+        // 手机端后台管理插件标识
202
+        $isMobile = input('param.isMobile/d', 0);
203
+
204
+        $admin_info = session('admin_info');
205
+        $auth_role_info = $admin_info['auth_role_info'];
206
+        $this->assign('auth_role_info', $auth_role_info);
207
+        $this->assign('admin_info', $admin_info);
208
+
209
+        if (IS_POST) {
210
+            $post = input('post.');
211
+            model('Archives')->editor_auto_210607($post);
212
+            //处理TAG标签
213
+            if (!empty($post['tags_new'])) {
214
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
215
+                unset($post['tags_new']);
216
+            }
217
+            $post['tags'] = explode(',', $post['tags']);
218
+            $post['tags'] = array_unique($post['tags']);
219
+            $post['tags'] = implode(',', $post['tags']);
220
+
221
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
222
+            if (!empty($post['restric_type']) && 0 < $post['restric_type']) {
223
+                $content = input('post.free_content', '', null);
224
+            }
225
+
226
+            // 如果安装后台手机端管理插件则执行
227
+            if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
228
+                // 调用逻辑层
229
+                $mbackendLogic = new \weapp\Mbackend\logic\MbackendLogic;
230
+                $contentData = $mbackendLogic->fileCacheHandle('get');
231
+                $content = !empty($contentData['content']) ? $contentData['content'] : '';
232
+                $post['addonFieldExt']['content'] = $post['addonFieldExt']['content_ey_m'] = $content;
233
+                $content = !empty($content) ? htmlspecialchars_decode($content) : '';
234
+            }
235
+
236
+            // 根据标题自动提取相关的关键字
237
+            $seo_keywords = $post['seo_keywords'];
238
+            if (!empty($seo_keywords)) {
239
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
240
+            } else {
241
+                // $seo_keywords = get_split_word($post['title'], $content);
242
+            }
243
+
244
+            // 自动获取内容第一张图片作为封面图
245
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
246
+            $litpic = '';
247
+            if ($is_remote == 1) {
248
+                $litpic = $post['litpic_remote'];
249
+            } else {
250
+                $litpic = $post['litpic_local'];
251
+            }
252
+            if (empty($litpic)) {
253
+                $litpic = get_html_first_imgurl($content);
254
+            }
255
+            $post['litpic'] = $litpic;
256
+
257
+            if (empty($post['litpic'])) {
258
+                $is_litpic = 0; // 无封面图
259
+            } else {
260
+                $is_litpic = 1; // 有封面图
261
+            }
262
+
263
+            // SEO描述
264
+            $seo_description = '';
265
+            if (empty($post['seo_description']) && !empty($content)) {
266
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
267
+            } else {
268
+                $seo_description = $post['seo_description'];
269
+            }
270
+
271
+            // 外部链接跳转
272
+            $jumplinks = '';
273
+            $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
274
+            if (intval($is_jump) > 0) {
275
+                $jumplinks = $post['jumplinks'];
276
+            }
277
+
278
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
279
+            if ($post['type_tempview'] == $post['tempview']) {
280
+                unset($post['type_tempview']);
281
+                unset($post['tempview']);
282
+            }
283
+
284
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
285
+            $htmlfilename = trim($post['htmlfilename']);
286
+            if (!empty($htmlfilename)) {
287
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
288
+                // $htmlfilename = strtolower($htmlfilename);
289
+                //判断是否存在相同的自定义文件名
290
+                $map = [
291
+                    'htmlfilename'  => $htmlfilename,
292
+                    'lang'  => $this->admin_lang,
293
+                ];
294
+                if (!empty($post['typeid'])) {
295
+                    $map['typeid'] = array('eq', $post['typeid']);
296
+                }
297
+                $filenameCount = Db::name('archives')->where($map)->count();
298
+                if (!empty($filenameCount)) {
299
+                    $this->error("同栏目下,自定义文件名已存在!");
300
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
301
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
302
+                }
303
+            } else {
304
+                // 处理外贸链接
305
+                if (is_dir('./weapp/Waimao/')) {
306
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
307
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'add', $this->globalConfig);
308
+                }
309
+            }
310
+            $post['htmlfilename'] = $htmlfilename;
311
+
312
+            //做自动通过审核判断
313
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
314
+                $post['arcrank'] = -1;
315
+            }
316
+
317
+            // 付费限制模式与之前三个字段 arc_level_id、 users_price、 users_free 组合逻辑兼容
318
+            $restricData = restric_type_logic($post, $this->channeltype);
319
+            if (isset($restricData['code']) && empty($restricData['code'])) {
320
+                $this->error($restricData['msg']);
321
+            }
322
+
323
+            // 副栏目
324
+            if (isset($post['stypeid'])) {
325
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
326
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
327
+                $post['stypeid'] = trim($post['stypeid'], ',');
328
+                $post['stypeid'] = str_replace(",{$post['typeid']},", ',', ",{$post['stypeid']},");
329
+                $post['stypeid'] = trim($post['stypeid'], ',');
330
+            }
331
+            
332
+            // 存储数据
333
+            $newData = array(
334
+                'typeid' => empty($post['typeid']) ? 0 : $post['typeid'],
335
+                'channel'   => $this->channeltype,
336
+                'is_b'      => empty($post['is_b']) ? 0 : $post['is_b'],
337
+                'is_head'      => empty($post['is_head']) ? 0 : $post['is_head'],
338
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
339
+                'is_recom'      => empty($post['is_recom']) ? 0 : $post['is_recom'],
340
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
341
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
342
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
343
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
344
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
345
+                'is_jump'     => $is_jump,
346
+                'is_litpic'     => $is_litpic,
347
+                'jumplinks' => $jumplinks,
348
+                'origin'      => empty($post['origin']) ? '网络' : $post['origin'],
349
+                'seo_keywords'     => $seo_keywords,
350
+                'seo_description'     => $seo_description,
351
+                'admin_id'  => session('admin_info.admin_id'),
352
+                'lang'  => $this->admin_lang,
353
+                'sort_order'    => 100,
354
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
355
+                'add_time'     => strtotime($post['add_time']),
356
+                'update_time'  => strtotime($post['add_time']),
357
+            );
358
+            $data = array_merge($post, $newData);
359
+            $aid = Db::name('archives')->insertGetId($data);
360
+            if (!empty($aid)) {
361
+                $_POST['aid'] = $aid;
362
+                if (!empty($post['restric_type']) && 0 < $post['restric_type']) {
363
+                    if (empty($post['size'])) {$post['size'] = 1;}
364
+                    $free_content = !empty($post['free_content']) ? $post['free_content'] : '';
365
+                    if (!empty($post['part_free']) && 2 == $post['part_free']){
366
+                        $free_content = htmlspecialchars_decode($post['addonFieldExt']['content']);
367
+                        $free_content = $this->SpLongBody($free_content, $post['size']);
368
+                        // $free_content = $this->SpLongBody($free_content,$post['size']*1024);
369
+                        $free_content = htmlspecialchars($free_content);
370
+                    }
371
+                    Db::name('article_pay')->insert([
372
+                        'aid'          => $aid,
373
+                        'part_free'    => isset($post['part_free']) ? intval($post['part_free']) : 0,
374
+                        'size'         => $post['size'],
375
+                        'free_content' => $free_content,
376
+                        'add_time'     => getTime(),
377
+                    ]);
378
+                }
379
+                model('Article')->afterSave($aid, $data, 'add');
380
+                // 添加查询执行语句到mysql缓存表
381
+                model('SqlCacheTable')->InsertSqlCacheTable();
382
+                adminLog('新增文章:'.$data['title']);
383
+
384
+                // 如果安装后台手机端管理插件则执行
385
+                if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
386
+                    // 调用逻辑层
387
+                    $mbackendLogic = new \weapp\Mbackend\logic\MbackendLogic;
388
+                    $mbackendLogic->fileCacheHandle('del');
389
+                }
390
+
391
+                // 生成静态页面代码
392
+                $successData = [
393
+                    'aid' => $aid,
394
+                    'tid' => $post['typeid'],
395
+                    'method'   =>'add',
396
+                ];
397
+                $this->success("操作成功!", null, $successData);
398
+            }
399
+            $this->error("操作失败!");
400
+        }
401
+
402
+        $typeid = input('param.typeid/d', 0);
403
+        $assign_data['typeid'] = $typeid;
404
+
405
+        $arctypeInfo = Db::name('arctype')->find($typeid);
406
+
407
+        //允许发布文档列表的栏目
408
+        $arctype_html = allow_release_arctype($typeid, array($this->channeltype));
409
+        $assign_data['arctype_html'] = $arctype_html;
410
+
411
+        // 阅读权限
412
+        $arcrank_list = get_arcrank_list();
413
+        $assign_data['arcrank_list'] = $arcrank_list;
414
+
415
+        // 模板列表
416
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
417
+        $templateList = $archivesLogic->getTemplateList($this->nid);
418
+        $assign_data['templateList'] = $templateList;
419
+
420
+        // 默认模板文件
421
+        $tempview = 'view_'.$this->nid.'.'.config('template.view_suffix');
422
+        !empty($arctypeInfo['tempview']) && $tempview = $arctypeInfo['tempview'];
423
+        $assign_data['tempview'] = $tempview;
424
+        
425
+        // 会员等级信息
426
+        $assign_data['users_level'] = model('UsersLevel')->getList('level_id, level_name, level_value');
427
+
428
+        // 文档默认浏览量
429
+        $globalConfig = tpCache('global');
430
+        if (isset($globalConfig['other_arcclick']) && 0 <= $globalConfig['other_arcclick']) {
431
+            $arcclick_arr = explode("|", $globalConfig['other_arcclick']);
432
+            if (count($arcclick_arr) > 1) {
433
+                $assign_data['rand_arcclick'] = mt_rand($arcclick_arr[0], $arcclick_arr[1]);
434
+            } else {
435
+                $assign_data['rand_arcclick'] = intval($arcclick_arr[0]);
436
+            }
437
+        }else{
438
+            $arcclick_config['other_arcclick'] = '500|1000';
439
+            tpCache('other', $arcclick_config);
440
+            $assign_data['rand_arcclick'] = mt_rand(500, 1000);
441
+        }
442
+
443
+        // URL模式
444
+        $tpcache = config('tpcache');
445
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
446
+
447
+        /*文档属性*/
448
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
449
+
450
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
451
+        $channelRow['data'] = json_decode($channelRow['data'], true);
452
+        $assign_data['channelRow'] = $channelRow;
453
+
454
+        // 来源列表
455
+        $system_originlist = tpSetting('system.system_originlist');
456
+        $system_originlist = json_decode($system_originlist, true);
457
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
458
+        $assign_data['system_originlist_0'] = !empty($system_originlist) ? $system_originlist[0] : "";
459
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
460
+
461
+        // 多站点,当用站点域名访问后台,发布文档自动选择当前所属区域
462
+        model('Citysite')->auto_location_select($assign_data);
463
+
464
+        $this->assign($assign_data);
465
+
466
+        // 如果安装手机端后台管理插件并且在手机端访问时执行
467
+        if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
468
+            $this->assign('arctypeInfo', $arctypeInfo);
469
+            return $this->display('archives/add');
470
+        } else {
471
+            return $this->fetch();
472
+        }
473
+    }
474
+
475
+    //编辑
476
+    public function edit()
477
+    {
478
+        // 手机端后台管理插件标识
479
+        $isMobile = input('param.isMobile/d', 0);
480
+
481
+        $admin_info = session('admin_info');
482
+        $auth_role_info = $admin_info['auth_role_info'];
483
+        $this->assign('auth_role_info', $auth_role_info);
484
+        $this->assign('admin_info', $admin_info);
485
+
486
+        if (IS_POST) {
487
+            $post = input('post.');
488
+            model('Archives')->editor_auto_210607($post);
489
+            $post['aid'] = intval($post['aid']);
490
+            // 处理TAG标签
491
+            if (!empty($post['tags_new'])) {
492
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
493
+                unset($post['tags_new']);
494
+            }
495
+            $post['tags'] = explode(',', $post['tags']);
496
+            $post['tags'] = array_unique($post['tags']);
497
+            $post['tags'] = implode(',', $post['tags']);
498
+
499
+            $typeid = input('post.typeid/d', 0);
500
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
501
+            if (!empty($post['restric_type']) && 0 < $post['restric_type']) {
502
+                $content = input('post.free_content', '', null);
503
+            }
504
+
505
+            // 如果安装后台手机端管理插件则执行
506
+            if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
507
+                // 调用逻辑层
508
+                $mbackendLogic = new \weapp\Mbackend\logic\MbackendLogic;
509
+                $contentData = $mbackendLogic->fileCacheHandle('get');
510
+                $content = !empty($contentData['content']) ? $contentData['content'] : '';
511
+                $post['addonFieldExt']['content'] = $post['addonFieldExt']['content_ey_m'] = $content;
512
+                $content = !empty($content) ? htmlspecialchars_decode($content) : '';
513
+            }
514
+
515
+            // 根据标题自动提取相关的关键字
516
+            $seo_keywords = $post['seo_keywords'];
517
+            if (!empty($seo_keywords)) {
518
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
519
+            } else {
520
+                // $seo_keywords = get_split_word($post['title'], $content);
521
+            }
522
+
523
+            // 自动获取内容第一张图片作为封面图
524
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
525
+            $litpic = '';
526
+            if ($is_remote == 1) {
527
+                $litpic = $post['litpic_remote'];
528
+            } else {
529
+                $litpic = $post['litpic_local'];
530
+            }
531
+            if (empty($litpic)) {
532
+                $litpic = get_html_first_imgurl($content);
533
+            }
534
+            $post['litpic'] = $litpic;
535
+
536
+            if (empty($post['litpic'])) {
537
+                $is_litpic = 0; // 无封面图
538
+            } else {
539
+                $is_litpic = !empty($post['is_litpic']) ? $post['is_litpic'] : 0; // 有封面图
540
+            }
541
+
542
+            // 勾选后SEO描述将随正文内容更新
543
+            $basic_update_seo_description = empty($post['basic_update_seo_description']) ? 0 : 1;
544
+            if (is_language()) {
545
+                $langRow = \think\Db::name('language')->order('id asc')
546
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
547
+                    ->select();
548
+                foreach ($langRow as $key => $val) {
549
+                    tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description], $val['mark']);
550
+                }
551
+            } else {
552
+                tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description]);
553
+            }
554
+            /*--end*/
555
+
556
+            // SEO描述
557
+            $seo_description = '';
558
+            if (!empty($basic_update_seo_description) || empty($post['seo_description'])) {
559
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
560
+            } else {
561
+                $seo_description = $post['seo_description'];
562
+            }
563
+
564
+            // 外部链接
565
+            $jumplinks = '';
566
+            $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
567
+            if (intval($is_jump) > 0) {
568
+                $jumplinks = $post['jumplinks'];
569
+            }
570
+
571
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
572
+            if ($post['type_tempview'] == $post['tempview']) {
573
+                unset($post['type_tempview']);
574
+                unset($post['tempview']);
575
+            }
576
+
577
+            // 同步栏目切换模型之后的文档模型
578
+            $channel = Db::name('arctype')->where(['id'=>$typeid])->getField('current_channel');
579
+
580
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
581
+            $htmlfilename = trim($post['htmlfilename']);
582
+            if (!empty($htmlfilename)) {
583
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
584
+                // $htmlfilename = strtolower($htmlfilename);
585
+                //判断是否存在相同的自定义文件名
586
+                $map = [
587
+                    'aid'   => ['NEQ', $post['aid']],
588
+                    'htmlfilename'  => $htmlfilename,
589
+                    'lang'  => $this->admin_lang,
590
+                ];
591
+                if (!empty($post['typeid'])) {
592
+                    $map['typeid'] = array('eq', $post['typeid']);
593
+                }
594
+                $filenameCount = Db::name('archives')->where($map)->count();
595
+                if (!empty($filenameCount)) {
596
+                    $this->error("同栏目下,自定义文件名已存在!");
597
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
598
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
599
+                }
600
+            } else {
601
+                // 处理外贸链接
602
+                if (is_dir('./weapp/Waimao/')) {
603
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
604
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'edit', $this->globalConfig);
605
+                }
606
+            }
607
+            $post['htmlfilename'] = $htmlfilename;
608
+
609
+            //做未通过审核文档不允许修改文档状态操作
610
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
611
+                $old_archives_arcrank = Db::name('archives')->where(['aid' => $post['aid']])->getField("arcrank");
612
+                if ($old_archives_arcrank < 0) {
613
+                    unset($post['arcrank']);
614
+                }
615
+            }
616
+
617
+            // 付费限制模式与之前三个字段 arc_level_id、 users_price、 users_free 组合逻辑兼容
618
+            $restricData = restric_type_logic($post, $this->channeltype);
619
+            if (isset($restricData['code']) && empty($restricData['code'])) {
620
+                $this->error($restricData['msg']);
621
+            }
622
+
623
+            // 副栏目
624
+            if (isset($post['stypeid'])) {
625
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
626
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
627
+                $post['stypeid'] = trim($post['stypeid'], ',');
628
+                $post['stypeid'] = str_replace(",{$typeid},", ',', ",{$post['stypeid']},");
629
+                $post['stypeid'] = trim($post['stypeid'], ',');
630
+            }
631
+
632
+            // 存储数据
633
+            $newData = array(
634
+                'typeid'=> $typeid,
635
+                'channel'   => $channel,
636
+                'is_b'      => empty($post['is_b']) ? 0 : $post['is_b'],
637
+                'is_head'      => empty($post['is_head']) ? 0 : $post['is_head'],
638
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
639
+                'is_recom'      => empty($post['is_recom']) ? 0 : $post['is_recom'],
640
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
641
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
642
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
643
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
644
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
645
+                'is_jump'   => $is_jump,
646
+                'is_litpic'     => $is_litpic,
647
+                'jumplinks' => $jumplinks,
648
+                'seo_keywords'     => $seo_keywords,
649
+                'seo_description'     => $seo_description,
650
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
651
+                'add_time'     => strtotime($post['add_time']),
652
+                'update_time'     => getTime(),
653
+            );
654
+            $data = array_merge($post, $newData);
655
+            $r = Db::name('archives')->where(['aid' => $data['aid'], 'lang'  => $this->admin_lang])->update($data);
656
+            if (!empty($r)) {
657
+                if (!empty($post['restric_type']) && 0 < $post['restric_type']) {
658
+                    if (empty($post['size'])) {$post['size'] = 1;}
659
+                    $free_content = !empty($post['free_content']) ? $post['free_content'] : '';
660
+                    if (!empty($post['part_free']) && 2 == $post['part_free']){
661
+                        $free_content = htmlspecialchars_decode($post['addonFieldExt']['content']);
662
+                        $free_content = $this->SpLongBody($free_content, $post['size']);
663
+                        // $free_content = $this->SpLongBody($free_content,$post['size']*1024);
664
+                        $free_content = htmlspecialchars($free_content);
665
+                    }
666
+                    $is_in = Db::name('article_pay')->where('aid',$data['aid'])->find();
667
+                    $article_pay_data = [
668
+                        'part_free' => isset($post['part_free']) ? intval($post['part_free']) : 0,
669
+                        'size'=> $post['size'],
670
+                        'free_content' => $free_content
671
+                    ];
672
+                    if (empty($is_in)){
673
+                        $article_pay_data['aid'] = $data['aid'];
674
+                        $article_pay_data['add_time'] = getTime();
675
+                        Db::name('article_pay')->insert($article_pay_data);
676
+                    }else{
677
+                        $article_pay_data['update_time'] = getTime();
678
+                        Db::name('article_pay')->where('aid',$data['aid'])->update($article_pay_data);
679
+                    }
680
+                }
681
+                model('Article')->afterSave($data['aid'], $data, 'edit');
682
+                adminLog('编辑文章:'.$data['title']);
683
+                
684
+                // 如果安装后台手机端管理插件则执行
685
+                if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
686
+                    // 调用逻辑层
687
+                    $mbackendLogic = new \weapp\Mbackend\logic\MbackendLogic;
688
+                    $mbackendLogic->fileCacheHandle('del');
689
+                }
690
+
691
+                // 生成静态页面代码
692
+                $successData = [
693
+                    'aid'       => $data['aid'],
694
+                    'tid'       => $typeid,
695
+                    'method'   =>'edit',
696
+                ];
697
+                $this->success("操作成功!", null, $successData);
698
+            }
699
+            $this->error("操作失败!");
700
+        }
701
+
702
+        $assign_data = array();
703
+        $id = input('id/d');
704
+        $info = model('Article')->getInfo($id, null, false);
705
+        if (empty($info)) $this->error('数据不存在,请联系管理员!');
706
+
707
+        if (!empty($info['users_price'])) {
708
+            $article_pay =  Db::name('article_pay')->field('part_free,free_content,size')->where('aid',$id)->find();
709
+            if (!empty($article_pay)){
710
+                $info = array_merge($article_pay ,$info);
711
+            }
712
+        }
713
+        // 兼容采集没有归属栏目的文档
714
+        if (empty($info['channel'])) {
715
+            $channelRow = Db::name('channeltype')->field('id as channel')
716
+                ->where('id',$this->channeltype)
717
+                ->find();
718
+            $info = array_merge($info, $channelRow);
719
+        }
720
+
721
+        $typeid = $info['typeid'];
722
+        $assign_data['typeid'] = $typeid;
723
+        
724
+        // 副栏目
725
+        $stypeid_arr = [];
726
+        if (!empty($info['stypeid'])) {
727
+            $info['stypeid'] = trim($info['stypeid'], ',');
728
+            $stypeid_arr = Db::name('arctype')->field('id,typename')->where(['id'=>['IN', $info['stypeid']],'is_del'=>0])->select();
729
+        }
730
+        $assign_data['stypeid_arr'] = $stypeid_arr;
731
+
732
+        // 栏目信息
733
+        $arctypeInfo = Db::name('arctype')->find($typeid);
734
+        $info['channel'] = $arctypeInfo['current_channel'];
735
+        if (is_http_url($info['litpic'])) {
736
+            $info['is_remote'] = 1;
737
+            $info['litpic_remote'] = handle_subdir_pic($info['litpic']);
738
+        } else {
739
+            $info['is_remote'] = 0;
740
+            $info['litpic_local'] = handle_subdir_pic($info['litpic']);
741
+        }
742
+    
743
+        // SEO描述
744
+        // if (!empty($info['seo_description'])) {
745
+        //     $info['seo_description'] = @msubstr(checkStrHtml($info['seo_description']), 0, config('global.arc_seo_description_length'), false);
746
+        // }
747
+        $assign_data['field'] = $info;
748
+
749
+        // 允许发布文档列表的栏目,文档所在模型以栏目所在模型为主,兼容切换模型之后的数据编辑
750
+        $arctype_html = allow_release_arctype($typeid, array($info['channel']));
751
+        $assign_data['arctype_html'] = $arctype_html;
752
+
753
+        // 阅读权限
754
+        $arcrank_list = get_arcrank_list();
755
+        $assign_data['arcrank_list'] = $arcrank_list;
756
+
757
+        // 模板列表
758
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
759
+        $templateList = $archivesLogic->getTemplateList($this->nid);
760
+        $assign_data['templateList'] = $templateList;
761
+
762
+        // 默认模板文件
763
+        $tempview = $info['tempview'];
764
+        empty($tempview) && $tempview = $arctypeInfo['tempview'];
765
+        $assign_data['tempview'] = $tempview;
766
+
767
+        // 会员等级信息
768
+        $assign_data['users_level'] = model('UsersLevel')->getList('level_id, level_name, level_value');
769
+
770
+        // URL模式
771
+        $tpcache = config('tpcache');
772
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
773
+
774
+        // 文档属性
775
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
776
+
777
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
778
+        $channelRow['data'] = json_decode($channelRow['data'], true);
779
+        $assign_data['channelRow'] = $channelRow;
780
+
781
+        // 来源列表
782
+        $system_originlist = tpSetting('system.system_originlist');
783
+        $system_originlist = json_decode($system_originlist, true);
784
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
785
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
786
+
787
+        $this->assign($assign_data);
788
+
789
+        // 如果安装手机端后台管理插件并且在手机端访问时执行
790
+        if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
791
+            return $this->display('archives/edit');
792
+        } else {
793
+            return $this->fetch();
794
+        }
795
+    }
796
+    
797
+    //删除
798
+    public function del()
799
+    {
800
+        if (IS_POST) {
801
+            $archivesLogic = new \app\admin\logic\ArchivesLogic;
802
+            $archivesLogic->del([], 0, 'article');
803
+        }
804
+    }
805
+    
806
+    //自动截取方法
807
+    function SpLongBody($mybody, $spsize)
808
+    {
809
+        // 新的字符截取逻辑 --- chenfy
810
+        return $this->handleFreeContent($mybody, $spsize);
811
+        exit;
812
+        if (strlen($mybody) < $spsize) {
813
+            return $mybody;
814
+        }
815
+        $mybody    = stripslashes($mybody);
816
+        $bds       = explode('<', $mybody);
817
+        $npageBody = '';
818
+        $istable   = 0;
819
+        $ret = '';
820
+        foreach ($bds as $i => $k) {
821
+            if ($i == 0) {
822
+                $npageBody .= $bds[$i];
823
+                continue;
824
+            }
825
+            $bds[$i] = "<" . $bds[$i];
826
+            if (strlen($bds[$i]) > 6) {
827
+                $tname = substr($bds[$i], 1, 5);
828
+                if (strtolower($tname) == 'table') {
829
+                    $istable++;
830
+                } else if (strtolower($tname) == '/tabl') {
831
+                    $istable--;
832
+                }
833
+                if ($istable > 0) {
834
+                    $npageBody .= $bds[$i];
835
+                    continue;
836
+                } else {
837
+                    $npageBody .= $bds[$i];
838
+                }
839
+            } else {
840
+                $npageBody .= $bds[$i];
841
+            }
842
+            if (strlen($npageBody) > $spsize) {
843
+                $ret = $npageBody;
844
+                break;
845
+            }
846
+        }
847
+        return $ret;
848
+    }
849
+
850
+    private function handleFreeContent($content = '', $freeSize = 0, $encoding = 'utf-8')
851
+    {
852
+        // 如果要截取的内容字数小于限制数字则原内容返回
853
+        if (mb_strlen($content, $encoding) < $freeSize) return $content;
854
+        $content = explode('<', stripslashes($content));
855
+        $isp = 0;
856
+        $istable = 0;
857
+        $result = '';
858
+        $freeContent = '';
859
+        foreach ($content as $key => $value) {
860
+            if (0 === intval($key) && !empty($value)) {
861
+                $freeContent .= $value;
862
+                continue;
863
+            }
864
+            $value = "<" . $value;
865
+            if (mb_strlen($value, $encoding) >= 4 && (false !== stripos($value, '<p>'))) {
866
+                if (false !== stripos($value, '<p>')) {
867
+                    $value = preg_replace('/<p>/i', '', $value);
868
+                    $strLength = mb_strlen($value, $encoding);
869
+                    $freeStrLength = '<' === $freeContent ? mb_strlen(preg_replace('/</i', '', $freeContent), $encoding) : mb_strlen($freeContent, $encoding);
870
+                    if (!empty($freeStrLength)) $freeSize = intval($freeSize) - intval($freeStrLength);
871
+                    if (intval($strLength) > intval($freeSize)) {
872
+                        $freeContent .= '<p>' . mb_substr($value, 0, $freeSize, 'utf-8') . '</p>';
873
+                    } else {
874
+                        $freeContent .= '<p>' . $value . '</p>';
875
+                    }
876
+                }
877
+                if (mb_strlen($freeContent, $encoding) > $freeSize) {
878
+                    $result = $freeContent;
879
+                    break;
880
+                }
881
+            } else {
882
+                if (strlen($value) > 6) {
883
+                    $tname = substr($value, 1, 5);
884
+                    if (strtolower($tname) == 'table') {
885
+                        $istable++;
886
+                    } else if (strtolower($tname) == '/tabl') {
887
+                        $istable--;
888
+                    }
889
+                    if ($istable > 0) {
890
+                        $freeContent .= $value;
891
+                        continue;
892
+                    } else {
893
+                        $freeContent .= $value;
894
+                    }
895
+                } else {
896
+                    $freeContent .= $value;
897
+                }
898
+                if (strlen($freeContent) > $freeSize) {
899
+                    $result = $freeContent;
900
+                    break;
901
+                }
902
+            }
903
+        }
904
+        $result = preg_replace('/<</i', '<', $result);
905
+        return $result;
906
+    }
907
+
908
+    //获取免费阅读部分
909
+    public function free_content($aid=0)
910
+    {
911
+        $free_content = '';
912
+        if (!empty($aid)){
913
+            $free_content = Db::name('article_pay')->where('aid',$aid)->value('free_content');
914
+        }
915
+        $this->assign('free_content', $free_content);
916
+        return $this->fetch();
917
+    }
918
+
919
+    //帮助
920
+    public function help()
921
+    {
922
+        $system_originlist = tpSetting('system.system_originlist');
923
+        $system_originlist = json_decode($system_originlist, true);
924
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
925
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
926
+        $this->assign($assign_data);
927
+
928
+        return $this->fetch();
929
+    }
930
+}

+ 593
- 0
application/admin/controller/Ask.php View File

@@ -0,0 +1,593 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+namespace app\admin\controller;
14
+
15
+use think\Page;
16
+use think\Db;
17
+use app\common\logic\ArctypeLogic;
18
+
19
+/**
20
+ * 插件的控制器
21
+ */
22
+class Ask extends Base
23
+{
24
+    private $arctypeLogic;
25
+   
26
+    /**
27
+     * 构造方法
28
+     */
29
+    public function _initialize()
30
+    {
31
+        parent::_initialize();
32
+
33
+        $functionLogic = new \app\common\logic\FunctionLogic;
34
+        $functionLogic->check_authorfile(2);
35
+
36
+        $this->arctypeLogic = new ArctypeLogic();
37
+        // 问题表
38
+        $this->ask_db = Db::name('ask');
39
+        // 答案表
40
+        $this->ask_answer_db = Db::name('ask_answer');
41
+        // 点赞表
42
+        $this->ask_answer_like_db = Db::name('ask_answer_like');
43
+        // 问题分类表
44
+        $this->ask_type_db = Db::name('ask_type');
45
+
46
+        $score_name = getUsersConfigData('score.score_name');
47
+        $this->assign('score_name', $score_name);
48
+    }
49
+
50
+    /**
51
+     * 插件后台管理 - 栏目管理
52
+     */
53
+    public function index()
54
+    {
55
+        $list = $this->ask_type_db->order('sort_order asc, type_id asc')->select();
56
+        foreach ($list as $key => $value) {
57
+            // 是否顶级栏目
58
+            if ($value['parent_id'] == 0) {
59
+                $PidData[] = $value;
60
+            } else {
61
+                $TidData[] = $value;
62
+            }
63
+        }
64
+
65
+        $list_new = [];
66
+        foreach ($PidData as $P_key => $PidValue) {
67
+            $type_name               = $PidValue['type_name'];
68
+            $PidValue['type_name_input']   = '<input type="text" name="type_name[]" value="' . $PidValue['type_name'] . '" class="w220">';
69
+            $PidValue['parent_name'] = '顶级栏目';
70
+            /*一级栏目*/
71
+            $list_new[] = $PidValue;
72
+            /* END */
73
+            foreach ($TidData as $T_key => $TidValue) {
74
+                /*二级栏目*/
75
+                if ($TidValue['parent_id'] == $PidValue['type_id']) {
76
+                    $TidValue['type_name_input']   = '|— <input type="text" name="type_name[]" value="' . $TidValue['type_name'] . '" class="w200">';
77
+                    $TidValue['parent_name'] = $type_name;
78
+                    $list_new[]              = $TidValue;
79
+                }
80
+                /* END */
81
+            }
82
+        }
83
+        $this->assign('list', $list_new);
84
+
85
+        /*栏目处理*/
86
+        $PidDataNew[0] = [
87
+            'type_id'   => 0,
88
+            'type_name' => '顶级栏目',
89
+            'parent_id' => 0,
90
+        ];
91
+        $PidData       = !empty($PidData) ? array_merge($PidDataNew, $PidData) : $PidDataNew;
92
+        $this->assign('PidData', $PidData);
93
+        /* END */
94
+
95
+        /*是否有数据*/
96
+        $IsEmpty = empty($list_new) ? 0 : 1;
97
+        $this->assign('IsEmpty', $IsEmpty);
98
+        /* END */
99
+        return $this->fetch();
100
+    }
101
+    
102
+    /**
103
+     * 插件后台管理 - 问题列表
104
+     */
105
+    public function ask_list()
106
+    {
107
+        $list     = array();
108
+        $keywords = input('keywords/s');
109
+        $map      = array();
110
+        if (!empty($keywords)) {
111
+            $map['a.ask_title'] = array('LIKE', "%{$keywords}%");
112
+        }
113
+        $map['a.is_del'] = 0;
114
+        $count   = $this->ask_db->alias('a')->where($map)->count('ask_id');// 查询满足要求的总记录数
115
+        $pageObj = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
116
+        $list    = $this->ask_db->field('a.*, b.type_name, b.parent_id')
117
+            ->alias('a')
118
+            ->join('__ASK_TYPE__ b', 'a.type_id = b.type_id', 'LEFT')
119
+            ->where($map)
120
+            ->order('a.is_review asc, a.ask_id desc')
121
+            ->limit($pageObj->firstRow . ',' . $pageObj->listRows)
122
+            ->select();
123
+        // 分类处理
124
+        if (!empty($list)) {
125
+            // 用户ID
126
+            $users_ids = [];
127
+            // 总分类数据
128
+            $TypeData = $this->ask_type_db->getField('type_id, type_name, parent_id');
129
+            foreach ($list as $key => $value) {
130
+                array_push($users_ids, $value['users_id']);
131
+
132
+                /*分类处理*/
133
+                if (!empty($value['parent_id'])) {
134
+                    $list[$key]['sub_type_name'] = $value['type_name'];
135
+                    $list[$key]['type_name']     = $TypeData[$value['parent_id']]['type_name'];
136
+                } else {
137
+                    $list[$key]['type_name']     = $value['type_name'];
138
+                    $list[$key]['sub_type_name'] = '';
139
+                }
140
+                /* END */
141
+
142
+                /*问题状态处理*/
143
+                if (0 == $value['status']) {
144
+                    $list[$key]['status'] = '<font color="red">未解决</font>';
145
+                } else if (1 == $value['status']) {
146
+                    $list[$key]['status'] = '已解决';
147
+                } else if (2 == $value['status']) {
148
+                    $list[$key]['status'] = '<font color="#cccccc">已关闭</font>';
149
+                }
150
+                /* END */
151
+
152
+                // 访问前台url
153
+                $list[$key]['HomeUrl'] = get_askurl("home/Ask/details", ['ask_id'=>$value['ask_id']]);
154
+            }
155
+
156
+            // 用户信息
157
+            $users_list = Db::name('users')->field('users_id, username, nickname, head_pic')->where(['users_id'=>['IN', $users_ids]])->getAllWithIndex('users_id');
158
+            $this->assign('users_list', $users_list);
159
+        }
160
+
161
+        $pageStr = $pageObj->show(); // 分页显示输出
162
+        $this->assign('list', $list); // 赋值数据集
163
+        $this->assign('page', $pageStr); // 赋值分页输出
164
+        $this->assign('pager', $pageObj); // 赋值分页对象
165
+        return $this->fetch('ask_list');
166
+    }
167
+
168
+    /**
169
+     * 插件后台管理 - 答案列表
170
+     */
171
+    public function answer()
172
+    {
173
+        $list     = array();
174
+        $keywords = input('keywords/s');
175
+        $map      = array();
176
+        if (!empty($keywords)) {
177
+            $map['a.content'] = array('LIKE', "%{$keywords}%");
178
+        }
179
+
180
+        $count   = $this->ask_answer_db->alias('a')->where($map)->count('answer_id');// 查询满足要求的总记录数
181
+        $pageObj = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
182
+        $list    = $this->ask_answer_db->field('a.*, b.nickname, b.username, b.head_pic')
183
+            ->alias('a')
184
+            ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
185
+            ->where($map)
186
+            ->order('a.is_review asc, a.answer_id desc')
187
+            ->limit($pageObj->firstRow . ',' . $pageObj->listRows)
188
+            ->select();
189
+
190
+        // 用户ID
191
+        $users_ids = [];
192
+        foreach ($list as $key => $value) {
193
+            array_push($users_ids, $value['users_id']);
194
+            // 访问前台url
195
+            $HomeAskUrl            = get_askurl("home/Ask/details", ['ask_id'=>$value['ask_id']]);
196
+            $list[$key]['HomeUrl'] = $HomeAskUrl;
197
+            $HomeAskUrl            .= !empty($value['answer_pid']) ? '#ul_div_li_' . $value['answer_pid'] : '#ul_div_li_' . $value['answer_id'];
198
+            $list[$key]['HomeAnswerUrl'] = $HomeAskUrl;
199
+
200
+            // 内容处理
201
+            $preg                  = '/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i';
202
+            $value['content']      = htmlspecialchars_decode($value['content']);
203
+            $value['content']      = preg_replace($preg, '[图片]', $value['content']);
204
+            $value['content']      = strip_tags($value['content']);
205
+            $list[$key]['content'] = mb_strimwidth($value['content'], 0, 120, "...");
206
+        }
207
+
208
+        $pageStr = $pageObj->show(); // 分页显示输出
209
+        $this->assign('list', $list); // 赋值数据集
210
+        $this->assign('page', $pageStr); // 赋值分页输出
211
+        $this->assign('pager', $pageObj); // 赋值分页对象
212
+
213
+        return $this->fetch('answer');
214
+    }
215
+
216
+    // 删除栏目
217
+    public function ask_type_del()
218
+    {
219
+        $type_id = input('del_id/a');
220
+        $type_id = eyIntval($type_id);
221
+        if (!empty($type_id)) {
222
+            $result     = $this->ask_type_db->where("type_id", 'IN', $type_id)->select();
223
+            $title_list = get_arr_column($result, 'type_name');
224
+
225
+            $r = $this->ask_type_db->where("type_id", 'IN', $type_id)->delete();
226
+            if ($r) {
227
+                adminLog('删除问答栏目:' . implode(',', $title_list));
228
+                // 同步删除顶级栏目下的子栏目
229
+                if (empty($result[0]['parent_id'])) {
230
+                    $this->ask_type_db->where("parent_id", 'IN', $type_id)->delete();
231
+                }
232
+                $this->success("删除成功!");
233
+            } else {
234
+                $this->error("删除失败!");
235
+            }
236
+        } else {
237
+            $this->error("参数有误!");
238
+        }
239
+    }
240
+
241
+    /**
242
+     * 插件后台管理 - 插件配置
243
+     */
244
+    public function conf()
245
+    {
246
+        if (IS_POST) {
247
+            $post     = input('post.');
248
+            $inc_type = 'ask';
249
+            tpSetting($inc_type, $post['ask']);
250
+
251
+            $functionLogic = new \app\common\logic\FunctionLogic;
252
+            $functionLogic->scoreConf($post['score']);
253
+
254
+            $this->success("操作成功");
255
+        }
256
+        $askConf = tpSetting('ask');
257
+        $this->assign('askConf', $askConf);
258
+
259
+        $score = getUsersConfigData('score');
260
+        $this->assign('score', $score);
261
+
262
+        return $this->fetch('conf');
263
+    }
264
+
265
+    public function level_set()
266
+    {
267
+        $LevelData = model('UsersLevel')->getList();
268
+        $this->assign('list', $LevelData);
269
+        return $this->fetch('level_set');
270
+
271
+    }
272
+
273
+    /**
274
+     * 栏目SEO配置
275
+     * @return [type] [description]
276
+     */
277
+    public function ask_type_seo()
278
+    {
279
+        $type_id = input('param.type_id/d');
280
+
281
+        if (IS_POST) {
282
+            if (empty($type_id)) {
283
+                $this->error('操作失败');
284
+            }
285
+
286
+            $data = input('post.');
287
+            $data['type_name'] = !empty($data['type_name']) ? trim($data['type_name']) : '';
288
+            $data['seo_title'] = !empty($data['seo_title']) ? trim($data['seo_title']) : '';
289
+            $data['seo_keywords'] = !empty($data['seo_keywords']) ? trim($data['seo_keywords']) : '';
290
+            $data['seo_description'] = !empty($data['seo_description']) ? trim($data['seo_description']) : '';
291
+            $data['update_time'] = getTime();
292
+
293
+            $r = $this->ask_type_db->where('type_id', $type_id)->update($data);
294
+            if (false !== $r) {
295
+                $this->success('操作成功!');
296
+            } else {
297
+                $this->error('操作失败!');
298
+            }
299
+        }
300
+
301
+        $info = $this->ask_type_db->where('type_id', $type_id)->find();
302
+        if (empty($info)) {
303
+            $this->error('数据不存在,请联系管理员!');
304
+            exit;
305
+        }
306
+        $this->assign('info', $info);
307
+
308
+        return $this->fetch('ask_type_seo');
309
+    }
310
+
311
+    /**
312
+     * 插件后台管理 - 删除问题
313
+     */
314
+    public function ask_del()
315
+    {
316
+        $ask_id = input('del_id/a');
317
+        $ask_id = eyIntval($ask_id);
318
+        if (!empty($ask_id)) {
319
+            $ask        = Db::name('ask')->where('ask_id', 'IN', $ask_id)->select();
320
+            $result     = $this->ask_db->where("ask_id", 'IN', $ask_id)->select();
321
+            $title_list = get_arr_column($result, 'ask_title');
322
+
323
+            $r = $this->ask_db->where("ask_id", 'IN', $ask_id)->update(['is_del'=>1]);
324
+            if ($r) {
325
+                adminLog('删除问题:' . implode(',', $title_list));
326
+                // 同步删除答案表数据
327
+                $this->ask_answer_db->where("ask_id", 'IN', $ask_id)->update(['is_del'=>1]);
328
+                // 同步删除点赞表数据
329
+                $this->ask_answer_like_db->where("ask_id", 'IN', $ask_id)->update(['is_del'=>1]);
330
+                /*afterDel start*/
331
+                foreach ($ask as $key => $val) {
332
+                    if (!empty($val['bestanswer_id'])){
333
+                        continue;
334
+                    }
335
+                    $users_id = $val['users_id'];
336
+                    $money    = $val['money'];
337
+                    if ($money > 0) {
338
+                        //退钱
339
+                        Db::name('users')->where('users_id', $users_id)->setInc('users_money', $money);
340
+                        $data = [
341
+                            'ask_id'   => $val['ask_id'],
342
+                            'users_id' => $users_id,
343
+                            'type'     => 4,//悬赏退回
344
+                            'money'    => $money,
345
+                        ];
346
+                        Db::name('users_score')->insert($data);
347
+                    }
348
+
349
+                }
350
+                /*afterDel end*/
351
+                $this->success("删除成功!");
352
+            } else {
353
+                $this->error("删除失败!");
354
+            }
355
+        } else {
356
+            $this->error("参数有误!");
357
+        }
358
+    }
359
+
360
+    /**
361
+     * 插件后台管理 - 批量审核问题
362
+     */
363
+    public function ask_review()
364
+    {
365
+        $ask_id = input('ask_id/a');
366
+        $ask_id = eyIntval($ask_id);
367
+        if (!empty($ask_id)) {
368
+            $UpData = [
369
+                'is_review'   => 1,
370
+                'update_time' => getTime(),
371
+            ];
372
+            $r      = $this->ask_db->where("ask_id", 'IN', $ask_id)->update($UpData);
373
+            if ($r) {
374
+                $this->success("审核成功!");
375
+            } else {
376
+                $this->error("审核失败!");
377
+            }
378
+        } else {
379
+            $this->error("参数有误!");
380
+        }
381
+    }
382
+
383
+    /**
384
+     * 插件后台管理 - 批量推荐问题
385
+     */
386
+    public function ask_recom()
387
+    {
388
+        $ask_id = input('ask_id/a');
389
+        $ask_id = eyIntval($ask_id);
390
+        if (!empty($ask_id)) {
391
+            $UpData = [
392
+                'is_recom'    => 1,
393
+                'update_time' => getTime(),
394
+            ];
395
+            $r      = $this->ask_db->where("ask_id", 'IN', $ask_id)->update($UpData);
396
+            if ($r) {
397
+                $this->success("审核成功!");
398
+            } else {
399
+                $this->error("审核失败!");
400
+            }
401
+        } else {
402
+            $this->error("参数有误!");
403
+        }
404
+    }
405
+
406
+    /**
407
+     * 插件后台管理 - 批量删除答案
408
+     */
409
+    public function answer_del()
410
+    {
411
+        $answer_id = input('del_id/a');
412
+        $answer_id = eyIntval($answer_id);
413
+        if (!empty($answer_id)) {
414
+            $r = $this->ask_answer_db->where("answer_id", 'IN', $answer_id)->delete();
415
+            if ($r) {
416
+                // 同步删除点赞表数据
417
+                $this->ask_answer_like_db->where("answer_id", 'IN', $answer_id)->delete();
418
+                $this->success("删除成功!");
419
+            } else {
420
+                $this->error("删除失败!");
421
+            }
422
+        } else {
423
+            $this->error("参数有误!");
424
+        }
425
+    }
426
+
427
+    /**
428
+     * 插件后台管理 - 批量审核答案
429
+     */
430
+    public function answer_review()
431
+    {
432
+        $answer_id = input('ask_id/a');
433
+        $answer_id = eyIntval($answer_id);
434
+        if (!empty($answer_id)) {
435
+            $UpData = [
436
+                'is_review'   => 1,
437
+                'update_time' => getTime(),
438
+            ];
439
+            $r      = $this->ask_answer_db->where("answer_id", 'IN', $answer_id)->update($UpData);
440
+            if ($r) {
441
+                $this->success("审核成功!");
442
+            } else {
443
+                $this->error("审核失败!");
444
+            }
445
+        } else {
446
+            $this->error("参数有误!");
447
+        }
448
+    }
449
+
450
+    /**
451
+     * 积分级别列表
452
+     * @return mixed
453
+     */
454
+    public function score_level()
455
+    {
456
+        if (IS_AJAX_POST){
457
+            $post = input('post.');
458
+
459
+            if (empty($post['name'])) {
460
+                $this->error('至少新增一个级别名称!');
461
+            } else {
462
+                $is_empty = true;
463
+                foreach ($post['name'] as $key => $val) {
464
+                    $val = trim($val);
465
+                    if (!empty($val)) {
466
+                        $is_empty = false;
467
+                        break;
468
+                    }
469
+                }
470
+                if (true === $is_empty) {
471
+                    $this->error('级别名称不能为空!');
472
+                }
473
+            }
474
+
475
+            // 处理新增数据
476
+            $AddAskData = [];
477
+            foreach ($post['name'] as $key => $value) {
478
+                $name  = trim($value);
479
+                if (empty($name)) {
480
+                    continue;
481
+                }
482
+
483
+                $id   = !empty($post['id'][$key]) ? intval($post['id'][$key]) : 0;
484
+                $min  = !empty($post['min'][$key]) ? intval($post['min'][$key]+1) : 0;
485
+                $max  = !empty($post['min'][$key+1]) ? intval($post['min'][$key+1]) : 0;
486
+
487
+                $AddAskData[] = [
488
+                    'id'   => $id,
489
+                    'name' => $name,
490
+                    'min'  => $min,
491
+                    'max'  => $max,
492
+                ];
493
+                if (empty($id)) {
494
+                    unset($AddAskData[$key]['id']);
495
+                }
496
+            }
497
+
498
+            // 添加\更新
499
+            $AskScoreLevelModel = new \app\common\model\AskScoreLevel;
500
+            if (!empty($AddAskData)) $ReturnId = $AskScoreLevelModel->saveAll($AddAskData);
501
+            if (!empty($ReturnId)) $this->success('保存成功');
502
+            $this->error('保存失败');
503
+        }
504
+
505
+        $list = Db::name('ask_score_level')->select();
506
+        $this->assign('list', $list);
507
+
508
+        return $this->fetch();
509
+    }
510
+
511
+    /**
512
+     * 删除积分级别
513
+     */
514
+    public function score_level_del()
515
+    {
516
+        $id = input('del_id/a');
517
+        $id = eyIntval($id);
518
+        if (!empty($id)) {
519
+            $r = Db::name('ask_score_level')->where("id", 'IN', $id)->delete();
520
+            if ($r) {
521
+                adminLog('删除问答积分级别表,id:' . implode(',', $id));
522
+                $this->success("删除成功!");
523
+            } else {
524
+                $this->error("删除失败!");
525
+            }
526
+        } else {
527
+            $this->error("参数有误!");
528
+        }
529
+    }
530
+
531
+    // 问答模型 - 保存栏目
532
+    public function ajax_ask_type_save()
533
+    {
534
+        if (IS_AJAX_POST) {
535
+            $post = input('post.');
536
+
537
+            if (empty($post['type_name'])) {
538
+                $this->error('至少新增一个栏目名称!');
539
+            } else {
540
+                $is_empty = true;
541
+                foreach ($post['type_name'] as $key => $val) {
542
+                    $val = trim($val);
543
+                    if (!empty($val)) {
544
+                        $is_empty = false;
545
+                        break;
546
+                    }
547
+                }
548
+                if (true === $is_empty) {
549
+                    $this->error('栏目名称不能为空!');
550
+                }
551
+            }
552
+
553
+            // 处理新增数据
554
+            $AddAskData = [];
555
+            foreach ($post['type_name'] as $key => $value) {
556
+                $type_name  = trim($value);
557
+                if (empty($type_name)) {
558
+                    continue;
559
+                }
560
+
561
+                $type_id    = $post['type_id'][$key];
562
+                $parent_id  = $post['parent_id'][$key];
563
+                $sort_order = $post['sort_order'][$key];
564
+
565
+                if (empty($parent_id) || $parent_id < 0) $parent_id = 0;
566
+
567
+                $AddAskData[] = [
568
+                    'type_id'     => $type_id,
569
+                    'type_name'   => $type_name,
570
+                    'parent_id'   => $parent_id,
571
+                    'sort_order'  => $sort_order,
572
+                    'update_time' => getTime(),
573
+                ];
574
+
575
+                if (empty($type_id)) {
576
+                    $AddAskData[$key]['seo_description'] = '';
577
+                    $AddAskData[$key]['lang']     = $this->admin_lang;
578
+                    $AddAskData[$key]['add_time'] = getTime();
579
+                    unset($AddAskData[$key]['type_id']);
580
+                }
581
+            }
582
+
583
+            // 添加\更新
584
+            $AskTypeModel = new \app\common\model\AskType;
585
+            if (!empty($AddAskData)) $ReturnId = $AskTypeModel->saveAll($AddAskData);
586
+
587
+            // 返回
588
+            if (!empty($ReturnId)) $this->success('操作成功');
589
+
590
+            $this->error('操作失败');
591
+        }
592
+    }
593
+}

+ 343
- 0
application/admin/controller/AuthRole.php View File

@@ -0,0 +1,343 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Validate;
19
+
20
+class AuthRole extends Base {
21
+    
22
+    public function _initialize() {
23
+        parent::_initialize();
24
+        $this->language_access(); // 多语言功能操作权限
25
+    }
26
+    
27
+    /**
28
+     * 权限组管理
29
+     */
30
+    public function index()
31
+    {   
32
+        $map = array();
33
+        $pid = input('pid/d');
34
+        $keywords = input('keywords/s');
35
+        $keywords = addslashes(trim($keywords));
36
+
37
+        if (!empty($keywords)) {
38
+            $map['c.name'] = array('LIKE', "%{$keywords}%");
39
+        }
40
+
41
+        $AuthRole =  Db::name('auth_role');
42
+        $count = $AuthRole->alias('c')->where($map)->count();// 查询满足要求的总记录数
43
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
44
+        $fields = "c.*,s.name AS pname";
45
+        $list = DB::name('auth_role')
46
+            ->field($fields)
47
+            ->alias('c')
48
+            ->join('__AUTH_ROLE__ s','s.id = c.pid','LEFT')
49
+            ->where($map)
50
+            ->order('c.id asc')
51
+            ->limit($Page->firstRow.','.$Page->listRows)
52
+            ->select();
53
+        $show = $Page->show();// 分页显示输出
54
+        $this->assign('page',$show);// 赋值分页输出
55
+        $this->assign('list',$list);// 赋值数据集
56
+        $this->assign('pager',$Page);// 赋值分页集
57
+
58
+        return $this->fetch();
59
+    }
60
+    
61
+    /**
62
+     * 新增权限组
63
+     */
64
+    public function add()
65
+    {
66
+        if (IS_POST) {
67
+            $rule = array(
68
+                'name'  => 'require',
69
+            );
70
+            $msg = array(
71
+                'name.require' => '权限组名称不能为空!',
72
+            );
73
+            $data = array(
74
+                'name' => trim(input('name/s')),
75
+            );
76
+            $validate = new Validate($rule, $msg);
77
+            $result   = $validate->check($data);
78
+            if(!$result){
79
+                $this->error($validate->getError());
80
+            }
81
+
82
+            $model = model('AuthRole');
83
+            $count = $model->where('name', $data['name'])->count();
84
+            if(! empty($count)){
85
+                $this->error('该权限组名称已存在,请检查');
86
+            }
87
+            $role_id = $model->saveAuthRole(input());
88
+            if($role_id){
89
+                adminLog('新增权限组:'.$data['name']);
90
+                $admin_role_list = model('AuthRole')->getRoleAll();
91
+                $this->success('操作成功', url('AuthRole/index'), ['role_id'=>$role_id,'role_name'=>$data['name'],'admin_role_list'=>json_encode($admin_role_list)]);
92
+            }else{
93
+                $this->error('操作失败');
94
+            }
95
+        }
96
+
97
+        // 权限组
98
+        $admin_role_list = model('AuthRole')->getRoleAll();
99
+        $this->assign('admin_role_list', $admin_role_list);
100
+
101
+        // 模块组
102
+        $modules = getAllMenu();
103
+        $this->assign('modules', $modules);
104
+
105
+        // 权限集
106
+        // $singleArr = array_multi2single($modules, 'child'); // 多维数组转为一维
107
+        $auth_rules = get_auth_rule(['is_modules'=>1]);
108
+        $auth_rule_list = group_same_key($auth_rules, 'menu_id');
109
+        foreach ($auth_rule_list as $key => $val) {
110
+            if (is_array($val)) {
111
+                $sort_order = [];
112
+                foreach ($val as $_k => $_v) {
113
+                    $sort_order[$_k]  = $_v['sort_order'];
114
+                }
115
+                array_multisort($sort_order, SORT_ASC, $val);
116
+                $auth_rule_list[$key] = $val;
117
+            }
118
+        }
119
+        $this->assign('auth_rule_list', $auth_rule_list);
120
+
121
+        // 栏目
122
+        $arctype_list = Db::name('arctype')->where([
123
+                'is_del'    => 0,
124
+            ])->order("grade desc")->select();
125
+        $arctype_p_html = $arctype_child_html = "";
126
+        $arctype_all = list_to_tree($arctype_list);
127
+        foreach ($arctype_all as $key => $arctype) {
128
+            if (!empty($arctype['children'])) {
129
+                if ($key > 0) {
130
+                    $arctype_p_html .= '<em class="arctype_bg expandable"></em>';
131
+                } else {
132
+                    $arctype_p_html .= '<em class="arctype_bg collapsable"></em>';
133
+                }
134
+                $arctype_child_html .= '<div class="arctype_child" id="arctype_child_' . $arctype['id'] . '"';
135
+                if ($arctype_all[0]['id'] == $arctype['id']) {
136
+                    $arctype_child_html .= ' style="display: block;" ';
137
+                }
138
+                $arctype_child_html .= '>';
139
+                $arctype_child_html .= $this->get_arctype_child_html($arctype);
140
+                $arctype_child_html .= '</div>';
141
+            }
142
+            $arctype_p_html .= '<label>' .
143
+                '<input type="checkbox" class="arctype_cbox arctype_id_' . $arctype['id'] . '" value="' . $arctype['id'] . '" ';
144
+            $arctype_p_html .= ' />' . $arctype['typename'] . '</label>&nbsp;';
145
+        }
146
+        $this->assign('arctype_p_html', $arctype_p_html);
147
+        $this->assign('arctype_child_html', $arctype_child_html);
148
+
149
+        // 插件
150
+        $plugins = false;
151
+        $web_weapp_switch = tpCache('global.web_weapp_switch');
152
+        if (1 == $web_weapp_switch) {
153
+            $plugins = model('Weapp')->getList(['status'=>1]);
154
+        }
155
+        $this->assign('plugins', $plugins);
156
+
157
+        return $this->fetch();
158
+    }
159
+
160
+    //xyz修改20220315
161
+    public function edit()
162
+    {
163
+        $id = input('param.id/d', 0);
164
+        if ($id <= 0) {
165
+            $this->error('非法访问');
166
+        }
167
+        if (IS_POST) {
168
+            $rule = array(
169
+                'name' => 'require',
170
+            );
171
+            $msg = array(
172
+                'name.require' => '权限组名称不能为空!',
173
+            );
174
+            $data = array(
175
+                'name' => trim(input('name/s')),
176
+            );
177
+            $validate = new Validate($rule, $msg);
178
+            $result = $validate->check($data);
179
+            if (!$result) {
180
+                $this->error($validate->getError());
181
+            }
182
+
183
+            $model = model('AuthRole');
184
+            $count = $model->where('name', $data['name'])
185
+                ->where('id', '<>', $id)
186
+                ->count();
187
+            if (!empty($count)) {
188
+                $this->error('该权限组名称已存在,请检查');
189
+            }
190
+            $role_id = $model->saveAuthRole(input(), true);
191
+            if ($role_id) {
192
+                adminLog('编辑权限组:' . $data['name']);
193
+                $this->success('操作成功', url('AuthRole/index'), ['role_id' => $role_id, 'role_name' => $data['name']]);
194
+            } else {
195
+                $this->error('操作失败');
196
+            }
197
+        }
198
+        $model = model('AuthRole');
199
+        $info = $model->getRole(array('id' => $id));
200
+        if (empty($info)) {
201
+            $this->error('数据不存在,请联系管理员!');
202
+        }
203
+        $this->assign('info', $info);
204
+        // 权限组
205
+        $admin_role_list = model('AuthRole')->getRoleAll();
206
+        $this->assign('admin_role_list', $admin_role_list);
207
+        // 模块组
208
+        $modules = getAllMenu();
209
+        $this->assign('modules', $modules);
210
+        // 权限集
211
+        $auth_rules = get_auth_rule(['is_modules' => 1]);
212
+        $auth_rule_list = group_same_key($auth_rules, 'menu_id');
213
+        foreach ($auth_rule_list as $key => $val) {
214
+            if (is_array($val)) {
215
+                $sort_order = [];
216
+                foreach ($val as $_k => $_v) {
217
+                    $sort_order[$_k] = $_v['sort_order'];
218
+                }
219
+                array_multisort($sort_order, SORT_ASC, $val);
220
+                $auth_rule_list[$key] = $val;
221
+            }
222
+        }
223
+        $this->assign('auth_rule_list', $auth_rule_list);
224
+
225
+        // 栏目
226
+        $arctype_list = Db::name('arctype')->where([
227
+            'is_del' => 0,
228
+        ])->order("grade desc")->select();
229
+        $arctype_p_html = $arctype_child_html = "";
230
+        $arctype_all = list_to_tree($arctype_list);
231
+        foreach ($arctype_all as $key => $arctype) {
232
+            if (!empty($arctype['children'])) {
233
+                if ($key > 0) {
234
+                    $arctype_p_html .= '<em class="arctype_bg expandable"></em>';
235
+                } else {
236
+                    $arctype_p_html .= '<em class="arctype_bg collapsable"></em>';
237
+                }
238
+                $arctype_child_html .= '<div class="arctype_child" id="arctype_child_' . $arctype['id'] . '"';
239
+                if ($arctype_all[0]['id'] == $arctype['id']) {
240
+                    $arctype_child_html .= ' style="display: block;" ';
241
+                }
242
+                $arctype_child_html .= '>';
243
+                $arctype_child_html .= $this->get_arctype_child_html($arctype,$info);
244
+                $arctype_child_html .= '</div>';
245
+            }
246
+            $arctype_p_html .= '<label>' .
247
+                '<input type="checkbox" class="arctype_cbox arctype_id_' . $arctype['id'] . '" value="' . $arctype['id'] . '" ';
248
+            if (!empty($info['permission']['arctype']) && in_array($arctype['id'], $info['permission']['arctype'])) {
249
+                $arctype_p_html .= ' checked="checked" ';
250
+            }
251
+            $arctype_p_html .= ' />' . $arctype['typename'] . '</label>&nbsp;';
252
+
253
+        }
254
+        $this->assign('arctype_p_html', $arctype_p_html);
255
+        $this->assign('arctype_child_html', $arctype_child_html);
256
+        
257
+        // 插件
258
+        $plugins = false;
259
+        $web_weapp_switch = tpCache('global.web_weapp_switch');
260
+        if (1 == $web_weapp_switch) {
261
+            $plugins = model('Weapp')->getList(['status'=>1]);
262
+        }
263
+        $this->assign('plugins', $plugins);
264
+
265
+        return $this->fetch();
266
+    }
267
+    /*
268
+     *  递归生成$arctype_child_html
269
+     *  $vo             栏目tree
270
+     *  $info           权限集合(用于edit是否已经选中)
271
+     *  return          完整html
272
+     */
273
+    private function get_arctype_child_html($vo,$info = []){
274
+        $arctype_child_html = "";
275
+        if (!empty($vo['children'])) {
276
+            $arctype_child_html .= '<div class="arctype_child1" id="arctype_child_' . $vo['id'] . '">';
277
+            //判断当前下级是否还存在下级,true为竖着,false为横着
278
+            $has_chldren = true;
279
+            if ($vo['grade'] != 0 && !empty($vo['has_chldren']) && $vo['has_chldren'] == count($vo['children'])){
280
+                $has_chldren = false;
281
+            }
282
+            if ($has_chldren){
283
+                foreach ($vo['children'] as $vo1) {
284
+                    $arctype_child_html .= '<div class="arctype_child1">';
285
+                    $arctype_child_html .= ' <span class="button level1 switch center_docu"></span>
286
+                                            <label><input type="checkbox" class="arctype_cbox arctype_id_' . $vo1['id'] . '" value="' . $vo1['id'] . '" data-pid="' . $vo1['parent_id'] . '" data-tpid="' . $vo['parent_id'] . '"';
287
+                    if (!empty($info['permission']['arctype']) && in_array($vo1['id'], $info['permission']['arctype'])) {
288
+                        $arctype_child_html .= ' checked="checked" ';
289
+                    }
290
+                    $arctype_child_html .= '/>' . $vo1['typename'] . '</label></div>';
291
+                    $arctype_child_html .= $this->get_arctype_child_html($vo1,$info);
292
+                }
293
+            }else{
294
+                $arctype_child_html .= '<div class="arctype_child2"> <span class="button level1 switch center_docu"></span>';
295
+                foreach ($vo['children'] as $vo1) {
296
+                    $arctype_child_html .= '<label><input type="checkbox" class="arctype_cbox arctype_id_' . $vo1['id'] . '" value="' . $vo1['id'] . '" data-pid="' . $vo1['parent_id'] . '" data-tpid="' . $vo['parent_id'] . '"';
297
+                    if (!empty($info['permission']['arctype']) && in_array($vo1['id'], $info['permission']['arctype'])) {
298
+                        $arctype_child_html .= ' checked="checked" ';
299
+                    }
300
+                    $arctype_child_html .= '/>' . $vo1['typename'] . '</label>';
301
+                    $arctype_child_html .= $this->get_arctype_child_html($vo1,$info);
302
+                }
303
+                $arctype_child_html .= '</div>';
304
+            }
305
+            $arctype_child_html .= '</div>';
306
+        }
307
+
308
+        return $arctype_child_html;
309
+    }
310
+    
311
+    public function del()
312
+    {
313
+        $id_arr = input('del_id/a');
314
+        $id_arr = eyIntval($id_arr);
315
+        if (!empty($id_arr)) {
316
+
317
+            $count = Db::name('auth_role')->where(['built_in'=>1,'id'=>['IN',$id_arr]])->count();
318
+            if (!empty($count)) {
319
+                $this->error('系统内置不允许删除!');
320
+            }
321
+
322
+            $role = Db::name('auth_role')->where("pid",'IN',$id_arr)->select();
323
+            if ($role) {
324
+                $this->error('请先清空该权限组下的子权限组');
325
+            }
326
+
327
+            $role_admin = Db::name('admin')->where("role_id",'IN',$id_arr)->select();
328
+            if ($role_admin) {
329
+                $this->error('请先清空所属该权限组的管理员');
330
+            } else {
331
+                $r = Db::name('auth_role')->where("id",'IN',$id_arr)->delete();
332
+                if($r){
333
+                    adminLog('删除权限组');
334
+                    $this->success('删除成功');
335
+                }else{
336
+                    $this->error('删除失败');
337
+                }
338
+            }
339
+        } else {
340
+            $this->error('参数有误');
341
+        }
342
+    }
343
+}

+ 288
- 0
application/admin/controller/Base.php View File

@@ -0,0 +1,288 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use app\admin\logic\UpgradeLogic;
16
+use think\Controller;
17
+use think\Db;
18
+use think\response\Json;
19
+use think\Session;
20
+class Base extends Controller {
21
+
22
+    public $session_id;
23
+    public $php_servicemeal = 0;
24
+    public $globalConfig = [];
25
+    public $usersConfig = [];
26
+
27
+    /**
28
+     * 析构函数
29
+     */
30
+    function __construct() 
31
+    {
32
+        if (!session_id()) {
33
+            Session::start();
34
+        }
35
+        header("Cache-control: private");  // history.back返回后输入框值丢失问题
36
+        parent::__construct();
37
+
38
+        $this->editor = tpSetting('editor');
39
+        if (empty($this->editor['editor_select'])) $this->editor['editor_select'] = 1;
40
+        $this->assign('editor', $this->editor);
41
+
42
+    }
43
+    
44
+    /*
45
+     * 初始化操作
46
+     */
47
+    public function _initialize() 
48
+    {
49
+        $this->session_id = session_id(); // 当前的 session_id
50
+        !defined('SESSION_ID') && define('SESSION_ID', $this->session_id); //将当前的session_id保存为常量,供其它方法调用
51
+
52
+        parent::_initialize();
53
+        $this->global_assign();
54
+
55
+       /*及时更新cookie中的admin_id,用于前台的可视化权限验证*/
56
+       // $auth_role_info = model('AuthRole')->getRole(array('id' => session('admin_info.role_id')));
57
+       // session('admin_info.auth_role_info', $auth_role_info);
58
+       /*--end*/
59
+
60
+        //过滤不需要登陆的行为
61
+        $ctl_act = CONTROLLER_NAME.'@'.ACTION_NAME;
62
+        $ctl_all = CONTROLLER_NAME.'@*';
63
+        $filter_login_action = config('filter_login_action');
64
+        $filter_login_action = empty($filter_login_action) ? [] : $filter_login_action;
65
+        if (in_array($ctl_act, $filter_login_action) || in_array($ctl_all, $filter_login_action) || !in_array(MODULE_NAME, ['admin'])) {
66
+            //return;
67
+        }else{
68
+            $web_login_expiretime = tpCache('global.web_login_expiretime');
69
+            empty($web_login_expiretime) && $web_login_expiretime = config('login_expire');
70
+            $admin_login_expire = session('admin_login_expire'); //最后登录时间
71
+            $admin_info = session('admin_info');
72
+            $isLogin = false; // 未登录
73
+            if (!empty($admin_info['admin_id']) && (getTime() - intval($admin_login_expire)) < $web_login_expiretime) {
74
+                $isLogin = $this->checkWechatLogin($admin_info); // 校验微信扫码登录
75
+                if (!IS_AJAX_POST) {
76
+                    session('admin_login_expire', getTime()); // 登录有效期
77
+                }
78
+                $this->check_priv();//检查管理员菜单操作权限
79
+            }
80
+
81
+            if (!$isLogin) {
82
+                /*自动退出*/
83
+                adminLog('访问后台');
84
+                session_unset();
85
+                session::clear();
86
+                cookie('admin-treeClicked', null); // 清除并恢复栏目列表的展开方式
87
+                cookie('admin-treeClicked-1649642233', null); // 清除并恢复内容管理的展开方式
88
+                /*--end*/
89
+                if (IS_AJAX) {
90
+                    $this->error('登录超时!');
91
+                } else {
92
+                    $url = request()->baseFile().'?s=Admin/login';
93
+                    $this->redirect($url);
94
+                    exit;
95
+                }
96
+            }
97
+        }
98
+
99
+        // 如果安装手机端后台管理插件并且在手机端访问时,自动重定向到手机端管理页面
100
+        $weappAjax = input('param.weappAjax/d', 0);
101
+        $actionArr = ['Weapp@execute', 'Admin@login', 'Admin@get_admin_wechat_users'];
102
+        $mbackendData = Db::name('weapp')->where('code', 'Mbackend')->getField('data');
103
+        $mbackendData = !empty($mbackendData) ? unserialize($mbackendData) : ['status'=>1];
104
+        if (is_dir('./weapp/Mbackend/') && !empty($mbackendData['status']) && isMobile() && empty($weappAjax) && !in_array($ctl_act, $actionArr)) {
105
+            $this->redirect(weapp_url('Mbackend/Mbackend/index'));
106
+        }
107
+
108
+        /* 增、改的跳转提示页,只限制于发布文档的模型和自定义模型 */
109
+        $channeltype_list = config('global.channeltype_list');
110
+        $controller_name = $this->request->controller();
111
+        $this->assign('controller_name', $controller_name);
112
+        if (isset($channeltype_list[strtolower($controller_name)]) || 'Custom' == $controller_name) {
113
+            if (in_array($this->request->action(), ['add','edit'])) {
114
+                $isMobile = input('param.isMobile/d', 0);
115
+                if (is_dir('./weapp/Mbackend/') && (isMobile() || !empty($isMobile))) {
116
+                    \think\Config::set('dispatch_success_tmpl', 'public/dispatch_jump_m');
117
+                } else {
118
+                    \think\Config::set('dispatch_success_tmpl', 'public/dispatch_jump');
119
+                }
120
+                $id = input('param.id/d', input('param.aid/d'));
121
+                ('GET' == $this->request->method()) && cookie('ENV_IS_UPHTML', 0);
122
+
123
+                // 解决没有从文档列表点击编辑的情况
124
+                $ENV_GOBACK_URL = cookie('ENV_GOBACK_URL');
125
+                empty($ENV_GOBACK_URL) && cookie('ENV_GOBACK_URL', url($controller_name.'/index'));
126
+                $ENV_LIST_URL = cookie('ENV_LIST_URL');
127
+                empty($ENV_LIST_URL) && cookie('ENV_LIST_URL', url($controller_name.'/index'));
128
+            } else if (in_array($this->request->action(), ['index'])) {
129
+                cookie('ENV_GOBACK_URL', $this->request->url());
130
+                cookie('ENV_LIST_URL', request()->baseFile()."?m=admin&c={$controller_name}&a=index&lang=".$this->admin_lang);
131
+            }
132
+        } else if ('Archives' == $controller_name && in_array($this->request->action(), ['index_archives','index_draft'])) {
133
+            cookie('ENV_GOBACK_URL', $this->request->url());
134
+            cookie('ENV_LIST_URL', request()->baseFile()."?m=admin&c=Archives&a=".$this->request->action()."&lang=".$this->admin_lang);
135
+        }
136
+
137
+        if (empty($this->globalConfig['seo_uphtml_after_home']) && empty($this->globalConfig['seo_uphtml_after_channel']) && empty($this->globalConfig['seo_uphtml_after_pernext'])) {
138
+            cookie('ENV_UPHTML_AFTER', null);
139
+        } else {
140
+            $seo_uphtml_after['seo_uphtml_after_home'] = !empty($this->globalConfig['seo_uphtml_after_home']) ? $this->globalConfig['seo_uphtml_after_home'] : 0;
141
+            $seo_uphtml_after['seo_uphtml_after_channel'] = !empty($this->globalConfig['seo_uphtml_after_channel']) ? $this->globalConfig['seo_uphtml_after_channel'] : 0;
142
+            $seo_uphtml_after['seo_uphtml_after_pernext'] = !empty($this->globalConfig['seo_uphtml_after_pernext']) ? $this->globalConfig['seo_uphtml_after_pernext'] : 0;
143
+            cookie('ENV_UPHTML_AFTER', json_encode($seo_uphtml_after));
144
+        }
145
+        /* end */
146
+    }
147
+
148
+    /**
149
+     * 校验微信扫码登录
150
+     * @param  array  $admin_info [description]
151
+     * @return [type]             [description]
152
+     */
153
+    private function checkWechatLogin($admin_info = [])
154
+    {
155
+        $isLogin = true;
156
+        if (is_dir('./weapp/Mbackend/') && isMobile()) {
157
+            return $isLogin;
158
+        }
159
+
160
+        $login_type = 1; //仅账号密码登录  2-账号密码登录&微信扫码登录 3-仅微信扫码登录
161
+        $thirdata = login_third_type();
162
+        $third_login = !empty($thirdata['type']) ? $thirdata['type'] : '';
163
+        $wx_map = ['admin_id'=>$admin_info['admin_id']];
164
+        if ('EyouGzhLogin' == $third_login) {
165
+            $wx_map['type'] = 1;
166
+            if (empty($thirdata['data']['force'])){
167
+                $login_type = 2; //2-账号密码登录&微信扫码登录
168
+            } else {
169
+                $login_type = 3; //仅微信扫码登录
170
+            }
171
+        } else if ('WechatLogin' == $third_login) {
172
+            $wx_map['type'] = 2;
173
+            if (empty($thirdata['data']['security_wechat_forcelogin'])) {
174
+                $login_type = 2; //2-账号密码登录&微信扫码登录
175
+            } else {
176
+                $login_type = 3; //仅微信扫码登录
177
+            }
178
+        }
179
+
180
+        if (!empty($third_login)) {
181
+            if (3 == $login_type || (!empty($admin_info['openid']) && 2 == $login_type)) {
182
+                $cacheKey = md5("admin_checkWechatLogin_".json_encode($wx_map));
183
+                $wx_info = cache($cacheKey);
184
+                if (empty($wx_info)) {
185
+                    $wx_info = Db::name('admin_wxlogin')->where($wx_map)->find();
186
+                    cache($cacheKey, $wx_info, null, "admin_wxlogin");
187
+                }
188
+                if (empty($admin_info['openid']) || empty($wx_info['openid']) || $admin_info['openid'] != $wx_info['openid']) {
189
+                    $isLogin = false;
190
+                    adminLog('重新登录验证');
191
+                    session_unset();
192
+                    session::clear();
193
+                    cookie('admin-treeClicked', null); // 清除并恢复栏目列表的展开方式
194
+                    cookie('admin-treeClicked-1649642233', null); // 清除并恢复内容管理的展开方式
195
+                    $url = request()->baseFile().'?s=Admin/login';
196
+                    $this->error('重新登录验证', $url);
197
+                }
198
+            }
199
+        }
200
+
201
+        return $isLogin;
202
+    }
203
+    
204
+    /**
205
+     * 检查管理员菜单操作权限
206
+     * @return [type] [description]
207
+     */
208
+    private function check_priv()
209
+    {
210
+        $ctl = CONTROLLER_NAME;
211
+        $act = ACTION_NAME;
212
+        $ctl_act = $ctl.'@'.$act;
213
+        $ctl_all = $ctl.'@*';
214
+        //无需验证的操作
215
+        $uneed_check_action = config('uneed_check_action');
216
+        if (0 >= intval(session('admin_info.role_id'))) {
217
+            //超级管理员无需验证
218
+            return true;
219
+        } else {
220
+            $bool = false;
221
+
222
+            /*检测是否有该权限*/
223
+            if (is_check_access($ctl_act)) {
224
+                $bool = true;
225
+            }
226
+            /*--end*/
227
+
228
+            /*在列表中的操作不需要验证权限*/
229
+            if (IS_AJAX || strpos($act,'ajax') !== false || in_array($ctl_act, $uneed_check_action) || in_array($ctl_all, $uneed_check_action)) {
230
+                $bool = true;
231
+            }
232
+            /*--end*/
233
+
234
+            if (is_dir('./weapp/Mbackend/') && isMobile()) {
235
+                $bool = true;
236
+            }
237
+
238
+            //检查是否拥有此操作权限
239
+            if (!$bool) {
240
+                $this->error('您没有操作权限,请联系超级管理员分配权限');
241
+            }
242
+        }
243
+    }
244
+
245
+    /**
246
+     * 保存系统设置 
247
+     */
248
+    public function global_assign()
249
+    {
250
+        /*随时更新每页记录数*/
251
+        $pagesize = input('get.pagesize/d');
252
+        if (!empty($pagesize)) {
253
+            $system_paginate_pagesize = config('tpcache.system_paginate_pagesize');
254
+            if ($pagesize != intval($system_paginate_pagesize)) {
255
+                tpCache('system', ['system_paginate_pagesize'=>$pagesize]);
256
+            }
257
+        }
258
+        /*end*/
259
+
260
+        $this->globalConfig = tpCache('global');
261
+        $this->php_servicemeal = $this->globalConfig['php_servicemeal'];
262
+        $this->globalConfig['web_loginlogo'] = handle_subdir_pic($this->globalConfig['web_loginlogo']);
263
+        $this->globalConfig['web_loginbgimg'] = handle_subdir_pic($this->globalConfig['web_loginbgimg']);
264
+        $this->globalConfig['web_adminlogo'] = handle_subdir_pic($this->globalConfig['web_adminlogo']);
265
+
266
+        $security = tpSetting('security');
267
+        empty($security) && $security = [];
268
+        !empty($security['security_verifyfunc']) && $security['security_verifyfunc'] = json_decode($security['security_verifyfunc'], true);
269
+        $this->globalConfig = array_merge($this->globalConfig, $security);
270
+        $this->assign('global', $this->globalConfig);
271
+
272
+        if (!empty($this->globalConfig['web_users_switch'])) {
273
+            $this->usersConfig = getUsersConfigData('all');
274
+        }
275
+        $this->assign('usersConfig', $this->usersConfig);
276
+    } 
277
+    
278
+    /**
279
+     * 多语言功能操作权限
280
+     */
281
+    public function language_access()
282
+    {
283
+        if (is_language() && $this->main_lang != $this->admin_lang) {
284
+            $lang_title = model('Language')->where('mark',$this->main_lang)->value('title');
285
+            $this->error('当前语言没有此功能,请切换到【'.$lang_title.'】语言');
286
+        }
287
+    }
288
+}

+ 460
- 0
application/admin/controller/Canal.php View File

@@ -0,0 +1,460 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+
19
+class Canal extends Base
20
+{
21
+    public function _initialize(){
22
+        parent::_initialize();
23
+    }
24
+
25
+    public function conf_api()
26
+    {
27
+        if (IS_AJAX_POST) {
28
+            $data = tpSetting("OpenMinicode.conf", [], $this->main_lang);
29
+            $data = json_decode($data, true);
30
+            empty($data) && $data = [];
31
+
32
+            $post = input('post.');
33
+            // if (isset($post['apikey'])) {
34
+            //     unset($post['apikey']);
35
+            // }
36
+            if ($post['apikey'] != $post['old_apikey']) {
37
+                $post['apikey_uptime'] = getTime();
38
+            }
39
+            $data = array_merge($data, $post);
40
+            tpSetting('OpenMinicode', ['conf' => json_encode($data)], $this->main_lang);
41
+            $this->success("操作成功");
42
+        }
43
+
44
+        // 同步微信配置
45
+        if (is_dir('./weapp/OpenMinicode/')) {
46
+            $admin_logic_1649404323 = tpSetting('syn.admin_logic_1649404323', [], 'cn');
47
+            if (empty($admin_logic_1649404323)) {
48
+                $minicode = Db::name('weapp')->where('code', 'OpenMinicode')->value('data');
49
+                $minicode = json_decode($minicode, true);
50
+                if (!empty($minicode['appid'])) {
51
+                    $data = [
52
+                        'appid'  => $minicode['appid'],
53
+                        'appsecret' => $minicode['secret'],
54
+                        'mchid'  => '',
55
+                        'apikey' => '',
56
+                    ];
57
+                    tpSetting('OpenMinicode', ['conf_weixin' => json_encode($data)], $this->main_lang);
58
+                }
59
+                tpSetting('syn', ['admin_logic_1649404323'=>1], 'cn');
60
+            }
61
+        }
62
+
63
+        $data = tpSetting("OpenMinicode.conf", [], $this->main_lang);
64
+        if (empty($data)) {
65
+            $data = [];
66
+            $data['apiopen'] = 0;
67
+            $data['apiverify'] = 0;
68
+            $data['apikey'] = get_rand_str(32, 0, 1);
69
+            tpSetting('OpenMinicode', ['conf' => json_encode($data)], $this->main_lang);
70
+        } else {
71
+            $data = json_decode($data, true);
72
+        }
73
+        $this->assign('data', $data);
74
+
75
+        //微信信息
76
+        $weixin_data = tpSetting("OpenMinicode.conf_weixin", [], $this->main_lang);
77
+        $weixin_data = json_decode($weixin_data, true);
78
+        $this->assign('weixin_data', $weixin_data);
79
+        // 小程序码
80
+        $weixin_qrcodeurl = "";
81
+        if (!empty($weixin_data['appid'])) {
82
+            $filepath = UPLOAD_PATH."allimg/20220515/wx-{$weixin_data['appid']}.png";
83
+            if (is_file($filepath)) {
84
+                $weixin_qrcodeurl = "{$this->root_dir}/".$filepath;
85
+            }
86
+        }
87
+        $this->assign('weixin_qrcodeurl', $weixin_qrcodeurl);
88
+        //百度信息
89
+        $baidu_data = tpSetting("OpenMinicode.conf_baidu", [], $this->main_lang);
90
+        $baidu_data = json_decode($baidu_data, true);
91
+        $this->assign('baidu_data', $baidu_data);
92
+
93
+        // 小程序码
94
+        $baidu_qrcodeurl = "";
95
+        if (!empty($baidu_data['appid'])) {
96
+            $filepath = UPLOAD_PATH."allimg/20220515/bd-{$baidu_data['appid']}.png";
97
+            if (is_file($filepath)) {
98
+                $baidu_qrcodeurl = "{$this->root_dir}/".$filepath;
99
+            }
100
+        }
101
+        $this->assign('baidu_qrcodeurl', $baidu_qrcodeurl);
102
+
103
+        // 抖音信息
104
+        $toutiao_data = tpSetting("OpenMinicode.conf_toutiao", [], $this->main_lang);
105
+        $toutiao_data = !empty($toutiao_data) ? json_decode($toutiao_data, true) : [];
106
+        $this->assign('toutiao_data', $toutiao_data);
107
+
108
+        return $this->fetch();
109
+    }
110
+
111
+    /**
112
+     * 重置API接口密钥
113
+     * @return [type] [description]
114
+     */
115
+    public function reset_apikey()
116
+    {
117
+        if (IS_AJAX_POST) {
118
+            $data = tpSetting("OpenMinicode.conf", [], $this->main_lang);
119
+            $data = json_decode($data, true);
120
+            empty($data) && $data = [];
121
+            $apikey = get_rand_str(32, 0, 1);
122
+            $data['apikey'] = $apikey;
123
+            // tpSetting('OpenMinicode', ['conf' => json_encode($data)], $this->main_lang);
124
+            $this->success("重置成功", null, ['apikey'=>$apikey]);
125
+        }
126
+    }
127
+
128
+    /**
129
+     * 微信小程序配置
130
+     * @return [type] [description]
131
+     */
132
+    public function conf_weixin()
133
+    {
134
+        if (IS_AJAX_POST) {
135
+            $post = input('post.');
136
+            $appid = !empty($post['appid']) ? trim($post['appid']) : trim($post['weixin_appid']);
137
+            $appsecret = !empty($post['appsecret']) ? trim($post['appsecret']) : trim($post['weixin_appsecret']);
138
+            $mchid = !empty($post['mchid']) ? trim($post['mchid']) : trim($post['weixin_mchid']);
139
+            $apikey = !empty($post['apikey']) ? trim($post['apikey']) : trim($post['weixin_apikey']);
140
+
141
+            if (!empty($appid) || !empty($appsecret)) {
142
+                if (empty($appid)) {
143
+                    $this->error('AppID不能为空!');
144
+                }
145
+                if (empty($appsecret)) {
146
+                    $this->error('AppSecret不能为空!');
147
+                }
148
+                $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;
149
+                $response = httpRequest($url);
150
+                $params = json_decode($response, true);
151
+                if (!empty($params['errcode'])) {
152
+                    if ($params['errcode'] == 40164) {
153
+                        preg_match_all('#(\d{1,3}\.){3}\d{1,3}#i', $params['errmsg'], $matches);
154
+                        $ip = !empty($matches[0][0]) ? $matches[0][0] : '';
155
+                        $ipTips = "<font color='red'>请将IP:{$ip} 加入微信小程序的IP白名单里!</font>";
156
+                        $this->error($ipTips);
157
+                    } else {
158
+                        $this->error($params['errmsg']);
159
+                    }
160
+                }
161
+
162
+                if (!empty($appid) && !empty($mchid) && !empty($apikey)) {
163
+                    $logic = new \app\api\logic\v1\ApiLogic;
164
+                    $returnData = $logic->GetWechatAppletsPay($appid, $mchid, $apikey);
165
+                    if (empty($returnData['code'])) {
166
+                        $this->error($returnData['msg']);
167
+                    }
168
+                }
169
+            }
170
+
171
+            $data = [
172
+                'appid'  => $appid,
173
+                'appsecret' => $appsecret,
174
+                'mchid'  => $mchid,
175
+                'apikey' => $apikey,
176
+            ];
177
+            tpSetting('OpenMinicode', ['conf_weixin' => json_encode($data)], $this->main_lang);
178
+            $this->success("操作成功");
179
+        }
180
+
181
+        $data = tpSetting("OpenMinicode.conf_weixin", [], $this->main_lang);
182
+        $data = json_decode($data, true);
183
+        $this->assign('data', $data);
184
+
185
+        // 小程序码
186
+        $qrcodeurl = "";
187
+        if (!empty($data['appid'])) {
188
+            $filepath = UPLOAD_PATH."allimg/20220515/wx-{$data['appid']}.png";
189
+            if (is_file($filepath)) {
190
+                $qrcodeurl = "{$this->root_dir}/".$filepath;
191
+            }
192
+        }
193
+        $this->assign('qrcodeurl', $qrcodeurl);
194
+
195
+        return $this->fetch();
196
+    }
197
+
198
+    /**
199
+     * 获取微信小程序码
200
+     * @return [type] [description]
201
+     */
202
+    public function ajax_get_weixin_qrcode()
203
+    {
204
+        $data = tpSetting("OpenMinicode.conf_weixin", [], $this->main_lang);
205
+        $data = json_decode($data, true);
206
+        $appid = !empty($data['appid']) ? $data['appid'] : '';
207
+        $appsecret = !empty($data['appsecret']) ? $data['appsecret'] : '';
208
+        if (!empty($appid) && !empty($appsecret)) {
209
+            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;
210
+            $response = httpRequest($url);
211
+            $params = json_decode($response, true);
212
+            if (isset($params['access_token'])) {
213
+                $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$params['access_token'];
214
+                $post_data = array(
215
+                    "scene" => 'test',
216
+                    "width" => 280,
217
+                );
218
+                $response = httpRequest($url, 'POST', json_encode($post_data, JSON_UNESCAPED_UNICODE));
219
+                $params = json_decode($response,true);
220
+                if (is_array($params) || $response === false) {
221
+                    $msg = !empty($params['errmsg']) ? $params['errmsg'] : '可能没发布小程序';
222
+                    $this->error($msg);
223
+                } else {
224
+                    $qrcodeurl = UPLOAD_PATH.'allimg/20220515';
225
+                    tp_mkdir($qrcodeurl);
226
+                    $qrcodeurl = $qrcodeurl."/wx-{$appid}.png";
227
+                    if (@file_put_contents($qrcodeurl, $response)){
228
+                        $qrcodeurl = $this->root_dir.'/'.$qrcodeurl;
229
+                        $this->success('生成小程序码成功', null, ['qrcodeurl'=>$qrcodeurl]);
230
+                    } else {
231
+                        $this->error('生成小程序码失败');
232
+                    }
233
+                }
234
+            }
235
+        }
236
+
237
+        $this->error('不存在信息');
238
+    }
239
+
240
+    /**
241
+     * 百度小程序配置
242
+     * @return [type] [description]
243
+     */
244
+    public function conf_baidu()
245
+    {
246
+        if (IS_AJAX_POST) {
247
+            $post = input('post.');
248
+            $appid = !empty($post['appid']) ? trim($post['appid']) : trim($post['baidu_appid']);
249
+            $appkey = !empty($post['appkey']) ? trim($post['appkey']) : trim($post['baidu_appkey']);
250
+            $appsecret = !empty($post['appsecret']) ? trim($post['appsecret']) : trim($post['baidu_appsecret']);
251
+
252
+            if (!empty($appid) || !empty($appkey) || !empty($appsecret)) {
253
+                if (empty($appid)) {
254
+                    $this->error('AppID不能为空!');
255
+                }
256
+                if (empty($appkey)) {
257
+                    $this->error('AppKey不能为空!');
258
+                }
259
+                if (empty($appsecret)) {
260
+                    $this->error('AppSecret不能为空!');
261
+                }
262
+
263
+                $url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={$appkey}&client_secret={$appsecret}&scope=smartapp_snsapi_base";
264
+                $response = httpRequest($url);
265
+                $params = json_decode($response, true);
266
+                if (!isset($params['access_token'])) {
267
+                    $this->error('AppID或AppSecret不正确!');
268
+                }
269
+            }
270
+
271
+            $data = [
272
+                'appid'  => $appid,
273
+                'appkey' => $appkey,
274
+                'appsecret'  => $appsecret,
275
+            ];
276
+            tpSetting('OpenMinicode', ['conf_baidu' => json_encode($data)], $this->main_lang);
277
+            $this->success("操作成功");
278
+        }
279
+
280
+        $data = tpSetting("OpenMinicode.conf_baidu", [], $this->main_lang);
281
+        $data = json_decode($data, true);
282
+        $this->assign('data', $data);
283
+
284
+        // 小程序码
285
+        $qrcodeurl = "";
286
+        if (!empty($data['appid'])) {
287
+            $filepath = UPLOAD_PATH."allimg/20220515/bd-{$data['appid']}.png";
288
+            if (is_file($filepath)) {
289
+                $qrcodeurl = "{$this->root_dir}/".$filepath;
290
+            }
291
+        }
292
+        $this->assign('qrcodeurl', $qrcodeurl);
293
+
294
+        return $this->fetch();
295
+    }
296
+
297
+    /**
298
+     * 获取百度小程序码
299
+     * @return [type] [description]
300
+     */
301
+    public function ajax_get_baidu_qrcode()
302
+    {
303
+        $data = tpSetting("OpenMinicode.conf_baidu", [], $this->main_lang);
304
+        $data = json_decode($data, true);
305
+        $appid = !empty($data['appid']) ? $data['appid'] : '';
306
+        $appkey = !empty($data['appkey']) ? $data['appkey'] : '';
307
+        $appsecret = !empty($data['appsecret']) ? $data['appsecret'] : '';
308
+        if (!empty($appkey) && !empty($appsecret)) {
309
+            $url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={$appkey}&client_secret={$appsecret}&scope=smartapp_snsapi_base";
310
+            $response = httpRequest($url);
311
+            $params = json_decode($response, true);
312
+            if (isset($params['access_token'])) {
313
+                $url = "https://openapi.baidu.com/rest/2.0/smartapp/qrcode/getv2";
314
+                $post_data = array(
315
+                    "access_token" => $params['access_token'],
316
+                );
317
+                $response = httpRequest($url, 'POST', $post_data);
318
+                $params = json_decode($response,true);
319
+                if (!isset($params['data']['base64_str'])) {
320
+                    $msg = !empty($params['errmsg']) ? $params['errmsg'] : '可能没发布小程序';
321
+                    $this->error($msg);
322
+                } else {
323
+                    $qrcodeurl = UPLOAD_PATH.'allimg/20220515';
324
+                    tp_mkdir($qrcodeurl);
325
+                    $qrcodeurl = $qrcodeurl."/bd-{$appid}.png";
326
+                    if (@file_put_contents($qrcodeurl, base64_decode($params['data']['base64_str']))){
327
+                        $qrcodeurl = $this->root_dir.'/'.$qrcodeurl;
328
+                        $this->success('生成小程序码成功', null, ['qrcodeurl'=>$qrcodeurl]);
329
+                    } else {
330
+                        $this->error('生成小程序码失败');
331
+                    }
332
+                }
333
+            }
334
+        }
335
+        $this->error('不存在信息');
336
+    }
337
+
338
+    /**
339
+     * 微信公众号配置
340
+     * @return [type] [description]
341
+     */
342
+    public function conf_wechat()
343
+    {
344
+        if (IS_AJAX_POST) {
345
+            $post = input('post.');
346
+            $appid = trim($post['appid']);
347
+            $appsecret = trim($post['appsecret']);
348
+
349
+            if (!empty($appid) || !empty($appsecret)) {
350
+                if (empty($appid)) {
351
+                    $this->error('AppID不能为空!');
352
+                }
353
+                if (empty($appsecret)) {
354
+                    $this->error('AppSecret不能为空!');
355
+                }
356
+
357
+                /*$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
358
+                $response = httpRequest($url);
359
+                $params = json_decode($response, true);
360
+                if (!isset($params['access_token'])) {
361
+                    $wechat_code = config('error_code.wechat');
362
+                    $msg = !empty($wechat_code[$params['errcode']]) ? $wechat_code[$params['errcode']] : $params['errmsg'];
363
+                    $this->error($msg);
364
+                }*/
365
+            }
366
+
367
+            $data = [
368
+                'appid'  => $appid,
369
+                'appsecret' => $appsecret,
370
+            ];
371
+
372
+            // 兼容老数据的功能,同步保存一份到以前配置里
373
+            $wechat_login_config = $this->usersConfig['wechat_login_config'];
374
+            $login_config = unserialize($wechat_login_config);
375
+            $data['wechat_name'] = !empty($login_config['wechat_name']) ? trim($login_config['wechat_name']) : '';
376
+            $data['wechat_pic'] = !empty($login_config['wechat_pic']) ? trim($login_config['wechat_pic']) : '';
377
+            getUsersConfigData('wechat', ['wechat_login_config'=>serialize($data)]);
378
+
379
+            tpSetting('OpenMinicode', ['conf_wechat' => json_encode($data)], $this->main_lang);
380
+
381
+            $this->success("操作成功");
382
+        }
383
+
384
+        $data = tpSetting("OpenMinicode.conf_wechat", [], $this->main_lang);
385
+        if (empty($data)) {
386
+            $wechat_login_config = getUsersConfigData('wechat.wechat_login_config');
387
+            $login_config = unserialize($wechat_login_config);
388
+            if (!empty($login_config)) {
389
+                $data = [];
390
+                $data['appid'] = !empty($login_config['appid']) ? trim($login_config['appid']) : '';
391
+                $data['appsecret'] = !empty($login_config['appsecret']) ? trim($login_config['appsecret']) : '';
392
+                $data['wechat_name'] = !empty($login_config['wechat_name']) ? trim($login_config['wechat_name']) : '';
393
+                $data['wechat_pic'] = !empty($login_config['wechat_pic']) ? trim($login_config['wechat_pic']) : '';
394
+                tpSetting('OpenMinicode', ['conf_wechat' => json_encode($data)], $this->main_lang);
395
+            }
396
+        } else {
397
+            $data = json_decode($data, true);
398
+        }
399
+        $this->assign('data', $data);
400
+        /*微站点配置*/
401
+        $login = !empty($this->usersConfig['wechat_login_config']) ? unserialize($this->usersConfig['wechat_login_config']) : [];
402
+        $this->assign('login', $login);
403
+        /* END */
404
+
405
+        /*验证IP是否加入白名单中*/
406
+        $ipTips = '';
407
+        if (!empty($data['appid']) && !empty($data['appsecret'])) {
408
+            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$data['appid']}&secret={$data['appsecret']}";
409
+            $res = json_decode(httpRequest($url), true);
410
+            if (!empty($res['errcode'])) {
411
+                if ($res['errcode'] == 40164) {
412
+                    preg_match_all('#(\d{1,3}\.){3}\d{1,3}#i', $res['errmsg'], $matches);
413
+                    $ip = !empty($matches[0][0]) ? $matches[0][0] : '';
414
+                    $ipTips = "<font color='red'>请将IP:{$ip} 加入微信公众号的IP白名单里,具体点击<a href=\"JavaScript:void(0);\" onclick=\"click_to_eyou_1575506523('https://www.eyoucms.com/plus/view.php?aid=9432&origin_eycms=1','IP白名单配置教程')\">查看教程</a>!</font>";
415
+                } else {
416
+                    $ipTips = "<font color='red'>{$res['errmsg']}</font>";
417
+                }
418
+            }
419
+        }
420
+        $this->assign('ipTips', $ipTips);
421
+        /*--end*/
422
+
423
+        return $this->fetch();
424
+    }
425
+
426
+    // 头条(抖音)配置
427
+    public function conf_toutiao()
428
+    {
429
+        if (IS_AJAX_POST) {
430
+            $post = input('post.');
431
+            $salt = !empty($post['salt']) ? trim($post['salt']) : trim($post['toutiao_salt']);
432
+            $appid = !empty($post['appid']) ? trim($post['appid']) : trim($post['toutiao_appid']);
433
+            $secret = !empty($post['appsecret']) ? trim($post['appsecret']) : trim($post['toutiao_appsecret']);
434
+            if (empty($appid)) $this->error('AppID不能为空!');
435
+            if (empty($secret)) $this->error('AppSecret不能为空!');
436
+            $params = getToutiaoAccessToken($appid, $secret, $salt, true);
437
+            if (empty($params['access_token'])) $this->error('AppID或AppSecret不正确!');
438
+            $this->success("操作成功");
439
+        }
440
+        $this->error('操作失败,请刷新重试');
441
+    }
442
+
443
+    /**
444
+     * 启用、关闭 开放API
445
+     * @return [type] [description]
446
+     */
447
+    public function ajax_save_apiopen()
448
+    {
449
+        if (IS_AJAX_POST) {
450
+            $apiopen = input('post.open_value/d');
451
+            $data = tpSetting("OpenMinicode.conf", [], $this->main_lang);
452
+            $data = json_decode($data, true);
453
+            empty($data) && $data = [];
454
+            $data['apiopen'] = $apiopen;
455
+            tpSetting('OpenMinicode', ['conf' => json_encode($data)], $this->main_lang);
456
+            $this->success('操作成功');
457
+        }
458
+    }
459
+
460
+}

+ 1163
- 0
application/admin/controller/Channeltype.php
File diff suppressed because it is too large
View File


+ 1640
- 0
application/admin/controller/Citysite.php
File diff suppressed because it is too large
View File


+ 399
- 0
application/admin/controller/Coupon.php View File

@@ -0,0 +1,399 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 陈风任 <491085389@qq.com>
11
+ * Date: 2019-2-12
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Config;
19
+use app\admin\logic\ShopLogic;
20
+
21
+class Coupon extends Base
22
+{
23
+    public $ShopLogic;
24
+    public $userConfig = [];
25
+
26
+    /**
27
+     * 构造方法
28
+     */
29
+    public function _initialize()
30
+    {
31
+        parent::_initialize();
32
+
33
+        $functionLogic = new \app\common\logic\FunctionLogic;
34
+        $functionLogic->validate_authorfile(2);
35
+        
36
+        $this->ShopLogic = new ShopLogic;
37
+        // 优惠券数据表
38
+        $this->shop_coupon_db     = Db::name('shop_coupon');
39
+        $this->shop_coupon_use_db = Db::name('shop_coupon_use');
40
+        // 商品数据表
41
+        $this->archives_db = Db::name('archives');
42
+        // 商品分类数据表
43
+        $this->arctype_db = Db::name('arctype');
44
+        // 默认商品模型
45
+        $this->channeltype = 2;
46
+        $this->assign('channeltype', $this->channeltype);
47
+        
48
+        // 列出营销功能里已使用的模块
49
+        $marketFunc = $this->ShopLogic->marketLogic();
50
+        if (!in_array('coupon', $marketFunc)) {
51
+            // $this->error('内置功能已废弃!');
52
+        }
53
+        $this->assign('marketFunc', $marketFunc);
54
+    }
55
+
56
+    // 优惠券列表
57
+    public function index()
58
+    {
59
+        $condition = [
60
+            'lang'   => $this->admin_lang,
61
+            'is_del' => 0
62
+        ];
63
+
64
+        $keywords = input('keywords/s');
65
+        // 应用搜索条件
66
+        if (!empty($keywords)) $condition['coupon_name'] = ['LIKE', "%{$keywords}%"];
67
+
68
+        // 分页
69
+        $count = $this->shop_coupon_db->where($condition)->count();
70
+        $Page  = new Page($count, config('paginate.list_rows'));
71
+        $show  = $Page->show();
72
+        $this->assign('page', $show);
73
+        $this->assign('pager', $Page);
74
+
75
+        // 数据查询
76
+        $list = $this->shop_coupon_db
77
+            ->where($condition)
78
+            ->order('sort_order asc, coupon_id desc')
79
+            ->limit($Page->firstRow . ',' . $Page->listRows)
80
+            ->select();
81
+        if (!empty($list)) {
82
+            $ids = [];
83
+            foreach ($list as $k => $v) {
84
+                $ids[] = $v['coupon_id'];
85
+            }
86
+            //已领数量
87
+            $getedArr = $this->shop_coupon_use_db->field('count(*) as count,coupon_id')->where('coupon_id', 'in', $ids)->group('coupon_id')->getAllWithIndex('coupon_id');
88
+            foreach ($list as $k => $v) {
89
+                $list[$k]['geted'] = $getedArr[$v['coupon_id']]['count'];
90
+            }
91
+        }
92
+
93
+        $this->assign('list', $list);
94
+
95
+        return $this->fetch();
96
+    }
97
+
98
+    // 新增优惠券
99
+    public function add()
100
+    {
101
+        if (IS_POST) {
102
+            $post = input('post.');
103
+            // 数据判断处理
104
+            if (empty($post['coupon_name'])) $this->error('请填写优惠券名称');
105
+            $post['coupon_name'] = htmlspecialchars_decode($post['coupon_name']);
106
+            if ('' == $post['conditions_use']) $this->error('请填写优惠规则-使用条件');
107
+            if (empty($post['coupon_price'])) $this->error('请填写优惠规则-减免金额');
108
+            if (empty($post['coupon_stock'])) $this->error('请填写库存');
109
+            if (1 == $post['use_type']) {
110
+                if (empty($post['use_start_time'])) $this->error('请填写优惠券有效开始时间');
111
+                if (empty($post['use_end_time'])) $this->error('请填写优惠券有效结束时间');
112
+            } else if (2 == $post['use_type'] || 3 == $post['use_type']) {
113
+                if (empty($post['valid_days'])) $this->error('请填写优惠券有效天数');
114
+            }
115
+            if (empty($post['start_date'])) $this->error('请选择优惠券发放日期');
116
+            if (empty($post['end_date'])) $this->error('请选择优惠券结束日期');
117
+            if (2 == $post['coupon_type']) {
118
+                if (empty($post['product_id'])) $this->error('请填写指定的商品ID');
119
+            }
120
+            $post['redeem_authority'] = !empty($post['level_id']) ? implode(',', $post['level_id']) : '';
121
+            $post['start_date']       = strtotime($post['start_date']);
122
+            $post['end_date']         = strtotime($post['end_date']);
123
+
124
+            $post['use_start_time'] = strtotime($post['use_start_time']);
125
+            $post['use_end_time']   = strtotime($post['use_end_time']);
126
+
127
+            $post['add_time']    = getTime();
128
+            $post['update_time'] = getTime();
129
+            $post['lang']        = $this->admin_lang;
130
+
131
+            if (1 == $post['coupon_type']) {
132
+                $post['product_id'] = '';
133
+                $post['arctype_id'] = '';
134
+            } else if (2 == $post['coupon_type']) {
135
+                $post['arctype_id'] = '';
136
+                // 去除重复项
137
+                $post['product_id'] = implode(',', array_unique(explode(',', $post['product_id'])));
138
+            } else if (3 == $post['coupon_type']) {
139
+                $post['product_id'] = '';
140
+            }
141
+            // 添加新优惠券
142
+            $ResultID = $this->shop_coupon_db->add($post);
143
+            if (!empty($ResultID)) {
144
+                $ResultID     = 2 > strlen($ResultID) ? '0' . $ResultID : $ResultID;
145
+                $coupon_code  = date('Ymd') . $ResultID;
146
+                $update_where = [
147
+                    'coupon_id' => $ResultID,
148
+                ];
149
+                $this->shop_coupon_db->where($update_where)->update(['coupon_code' => $coupon_code]);
150
+                $this->success('操作成功', url('Coupon/index'));
151
+            } else {
152
+                $this->error('操作失败');
153
+            }
154
+        }
155
+
156
+        // 会员级别
157
+        $users_level = model('UsersLevel')->getList();
158
+        $this->assign('users_level', $users_level);
159
+
160
+        // 开始时间
161
+        $start_date = date("Y-m-d H:i:s", strtotime("-0 day"));
162
+        $this->assign('start_date', $start_date);
163
+
164
+        // 结束时间
165
+        $end_date = date("Y-m-d H:i:s", strtotime("+15 day"));
166
+        $this->assign('end_date', $end_date);
167
+        return $this->fetch();
168
+    }
169
+
170
+    // 优惠券编辑
171
+    public function edit()
172
+    {
173
+        if (IS_POST) {
174
+            $post = input('post.');
175
+            $post['coupon_id'] = intval($post['coupon_id']);
176
+            // 数据判断处理
177
+            if (empty($post['coupon_name'])) $this->error('请填写优惠券名称');
178
+            $post['coupon_name'] = htmlspecialchars_decode($post['coupon_name']);
179
+            if ('' == $post['conditions_use']) $this->error('请填写优惠规则-使用条件');
180
+            if (empty($post['coupon_price'])) $this->error('请填写优惠规则-减免金额');
181
+            if (empty($post['coupon_stock'])) $this->error('请填写库存');
182
+            if (1 == $post['use_type']) {
183
+                if (empty($post['use_start_time'])) $this->error('请填写优惠券有效开始时间');
184
+                if (empty($post['use_end_time'])) $this->error('请填写优惠券有效结束时间');
185
+            } else if (2 == $post['use_type'] || 3 == $post['use_type']) {
186
+                if (empty($post['valid_days'])) $this->error('请填写优惠券有效天数');
187
+            }
188
+            if (empty($post['start_date'])) $this->error('请选择优惠券发放日期');
189
+            if (empty($post['end_date'])) $this->error('请选择优惠券结束日期');
190
+            if (2 == $post['coupon_type']) {
191
+                if (empty($post['product_id'])) $this->error('请填写指定的商品ID');
192
+            }
193
+            $post['redeem_authority'] = !empty($post['level_id']) ? implode(',', $post['level_id']) : '';
194
+            $post['start_date']       = strtotime($post['start_date']);
195
+            $post['end_date']         = strtotime($post['end_date']);
196
+            $post['use_start_time']   = strtotime($post['use_start_time']);
197
+            $post['use_end_time']     = strtotime($post['use_end_time']);
198
+            $post['update_time']      = getTime();
199
+            if (1 == $post['coupon_type']) {
200
+                $post['product_id'] = '';
201
+                $post['arctype_id'] = '';
202
+            } else if (2 == $post['coupon_type']) {
203
+                $post['arctype_id'] = '';
204
+            } else if (3 == $post['coupon_type']) {
205
+                $post['product_id'] = '';
206
+            }
207
+            $update_where = [
208
+                'coupon_id' => $post['coupon_id'],
209
+            ];
210
+            // 更新优惠券
211
+            $ResultID = $this->shop_coupon_db->where($update_where)->update($post);
212
+            if (!empty($ResultID)) {
213
+                $this->success('更新成功', url('Coupon/index'));
214
+            } else {
215
+                $this->error('更新失败');
216
+            }
217
+        }
218
+        $shop_coupon_where = [
219
+            'coupon_id' => input('id/d'),
220
+        ];
221
+        // 优惠券数据
222
+        $shop_coupon                     = $this->shop_coupon_db->where($shop_coupon_where)->find();
223
+        $shop_coupon['redeem_authority'] = explode(',', $shop_coupon['redeem_authority']);
224
+        $shop_coupon['product_id_num']   = !empty($shop_coupon['product_id']) ? count(explode(',', $shop_coupon['product_id'])) : 0;
225
+        $shop_coupon['arctype_id_num']   = !empty($shop_coupon['arctype_id']) ? count(explode(',', $shop_coupon['arctype_id'])) : 0;
226
+        $this->assign('info', $shop_coupon);
227
+
228
+        // 会员级别
229
+        $users_level = model('UsersLevel')->getList();
230
+        $this->assign('users_level', $users_level);
231
+        return $this->fetch();
232
+    }
233
+
234
+    // 优惠券删除
235
+    public function del()
236
+    {
237
+        $coupon_id = input('del_id/a');
238
+        $coupon_id = eyIntval($coupon_id);
239
+        if (IS_AJAX_POST && !empty($coupon_id)) {
240
+            // 删除统一条件
241
+            $Where            = [
242
+                'coupon_id' => ['IN', $coupon_id],
243
+            ];
244
+            $result           = $this->shop_coupon_db->field('coupon_name')->where($Where)->select();
245
+            $coupon_name_list = get_arr_column($result, 'coupon_name');
246
+
247
+            $return = $this->shop_coupon_db->where($Where)->update(['is_del'=>1,'update_time'=>getTime()]);
248
+            if ($return) {
249
+                adminLog('删除优惠券:' . implode(',', $coupon_name_list));
250
+                $this->success('删除成功');
251
+            } else {
252
+                $this->error('删除失败');
253
+            }
254
+        }
255
+        $this->error('参数有误');
256
+    }
257
+
258
+    // 选择商品
259
+    public function select_product()
260
+    {
261
+        // 查询条件
262
+        $where['a.channel'] = $this->channeltype;
263
+        $where['a.status']  = 1;
264
+        $where['a.is_del']  = 0;
265
+        $where['a.lang']    = $this->admin_lang;
266
+
267
+        $keywords = input('keywords/s');
268
+        if (!empty($keywords)) $where['a.title'] = ['LIKE', "%{$keywords}%"];
269
+
270
+        // 指定商品ID查询
271
+        $product_ids = input('product_ids/s');
272
+        if (!empty($product_ids)) $where['a.aid'] = ['IN', explode(',', $product_ids)];
273
+
274
+        // 指定分类查询
275
+        $typeid = input('typeid/d') ? input('typeid/d') : 0;
276
+        if (!empty($typeid)) {
277
+            $hasRow            = model('Arctype')->getHasChildren($typeid);
278
+            $typeids           = get_arr_column($hasRow, 'id');
279
+            $where['a.typeid'] = ['IN', $typeids];
280
+        }
281
+
282
+        $count   = $this->archives_db->alias('a')->where($where)->count();
283
+        $pageObj = new Page($count, config('paginate.list_rows'));
284
+        $this->assign('page', $pageObj->show());
285
+        $this->assign('pager', $pageObj);
286
+
287
+        $field      = 'a.aid, a.litpic, a.aid as product_id, a.title, a.users_price, b.typename';
288
+        $ResultData = $this->archives_db
289
+            ->alias('a')
290
+            ->field($field)
291
+            ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
292
+            ->where($where)
293
+            ->order('a.sort_order asc, a.users_price desc, a.aid desc')
294
+            ->limit($pageObj->firstRow . ',' . $pageObj->listRows)
295
+            ->select();
296
+        $array_new  = get_archives_data($ResultData, 'aid');
297
+        foreach ($ResultData as $key => $value) {
298
+            $ResultData[$key]['arcurl'] = get_arcurl($array_new[$value['aid']]);
299
+            $ResultData[$key]['litpic'] = handle_subdir_pic($value['litpic']);
300
+        }
301
+
302
+        $this->assign('list', $ResultData);
303
+
304
+        /*允许发布文档列表的栏目*/
305
+        $arctype_html = allow_release_arctype($typeid, [$this->channeltype]);
306
+        $this->assign('arctype_html', $arctype_html);
307
+        $this->assign('typeid', $typeid);
308
+        /*--end*/
309
+        return $this->fetch();
310
+    }
311
+
312
+    // 获取指定分类或查询后的所有商品ID
313
+    public function ajax_get_product_id()
314
+    {
315
+        if (IS_AJAX_POST) {
316
+            $post = input('post.');
317
+
318
+            // 查询条件
319
+            $where['a.channel'] = $this->channeltype;
320
+            $where['a.status']  = 1;
321
+            $where['a.is_del']  = 0;
322
+            $where['a.lang']    = $this->admin_lang;
323
+
324
+            $keywords = input('keywords/s');
325
+            if (!empty($keywords)) $where['a.title'] = ['LIKE', "%{$keywords}%"];
326
+
327
+            // 指定商品ID查询
328
+            $product_ids = input('product_ids/s');
329
+            if (!empty($product_ids)) $where['a.aid'] = ['IN', explode(',', $product_ids)];
330
+
331
+            // 指定分类查询
332
+            $typeid = input('typeid/d') ? input('typeid/d') : 0;
333
+            if (!empty($typeid)) {
334
+                $hasRow            = model('Arctype')->getHasChildren($typeid);
335
+                $typeids           = get_arr_column($hasRow, 'id');
336
+                $where['a.typeid'] = ['IN', $typeids];
337
+            }
338
+
339
+            $field      = 'a.aid, a.aid as product_id';
340
+            $ResultData = $this->archives_db
341
+                ->alias('a')
342
+                ->field($field)
343
+                ->where($where)
344
+                ->order('a.sort_order asc, a.users_price desc, a.aid desc')
345
+                ->select();
346
+
347
+            $product_ids              = get_arr_column($ResultData, 'product_id');
348
+            $ReturnData['ProductNum'] = count($ResultData);
349
+            $ReturnData['ProductIDS'] = implode(',', $product_ids);
350
+            $this->success('', null, $ReturnData);
351
+        }
352
+    }
353
+
354
+    /**
355
+     * 选择分类
356
+     * @return [type] [description]
357
+     */
358
+    public function select_arctype()
359
+    {
360
+        $assign_data = [];
361
+        // 目录列表
362
+        $where = [];
363
+        $where['current_channel'] = $this->channeltype;
364
+        $where['is_del'] = 0; // 回收站功能
365
+        $arctypeLogic = new \app\common\logic\ArctypeLogic;
366
+        $arctype_list = $arctypeLogic->arctype_list(0, 0, false, 0, $where, false);
367
+        $assign_data['arctype_list'] = $arctype_list;
368
+
369
+        /*获取所有有子栏目的栏目id*/
370
+        $parent_ids = Db::name('arctype')->where([
371
+                'parent_id' => ['gt', 0],
372
+                'is_del'    => 0,
373
+            ])->group('parent_id')->cache(true, EYOUCMS_CACHE_TIME, 'arctype')->column('parent_id');
374
+        $cookied_treeclicked =  json_decode(cookie('coupontypeids-treeClicked-Arr'));
375
+        empty($cookied_treeclicked) && $cookied_treeclicked = [];
376
+        $all_treeclicked = cookie('coupontypeids-treeClicked_All');
377
+        empty($all_treeclicked) && $all_treeclicked = [];
378
+        $tree = [
379
+            'has_children'=>!empty($parent_ids) ? 1 : 0,
380
+            'parent_ids'=>json_encode($parent_ids),
381
+            'all_treeclicked'=>$all_treeclicked,
382
+            'cookied_treeclicked'=>$cookied_treeclicked,
383
+            'cookied_treeclicked_arr'=>json_encode($cookied_treeclicked),
384
+        ];
385
+        $assign_data['tree'] = $tree;
386
+        /* end */
387
+
388
+        // 分类
389
+        $typeids = input('param.typeids/s');
390
+        $typeids = trim($typeids, ',');
391
+        $typeids_arr = explode(',', $typeids);
392
+        $assign_data['typeids'] = $typeids;
393
+        $assign_data['typeids_arr'] = $typeids_arr;
394
+
395
+        $this->assign($assign_data);
396
+
397
+        return $this->fetch();
398
+    }
399
+}

+ 1085
- 0
application/admin/controller/Custom.php
File diff suppressed because it is too large
View File


+ 540
- 0
application/admin/controller/Discount.php View File

@@ -0,0 +1,540 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+
19
+class Discount extends Base
20
+{
21
+    /**
22
+     * 构造方法
23
+     */
24
+    public function _initialize()
25
+    {
26
+        parent::_initialize();
27
+
28
+        $functionLogic = new \app\common\logic\FunctionLogic;
29
+        $functionLogic->validate_authorfile(2);
30
+    }
31
+    
32
+    /**
33
+     * 限时折扣商品列表
34
+     */
35
+    public function index()
36
+    {
37
+        $list     = array();
38
+        $keywords = input('keywords/s');
39
+
40
+        $condition = array();
41
+        if (!empty($keywords)) {
42
+            $condition['b.title'] = array('LIKE', "%{$keywords}%");
43
+        }
44
+
45
+        $fields = "a.*,b.title,b.litpic";
46
+
47
+        $Db    = Db::name('discount_goods');
48
+        $count = $Db->alias("a")->join('archives b', "a.aid=b.aid")->where($condition)->count('a.discount_gid');// 查询满足要求的总记录数
49
+        $Page  = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
50
+        $list  = $Db->alias("a")->field($fields)
51
+            ->join('archives b', "a.aid=b.aid")
52
+            ->where($condition)
53
+            ->order('a.sort_order asc, a.discount_gid desc')
54
+            ->limit($Page->firstRow . ',' . $Page->listRows)
55
+            ->select();
56
+
57
+        $show = $Page->show();// 分页显示输出
58
+        $this->assign('page', $show);// 赋值分页输出
59
+        $this->assign('list', $list);// 赋值数据集
60
+        $this->assign('pager', $pager);// 赋值分页对象
61
+        return $this->fetch();
62
+    }
63
+
64
+    /**
65
+     * 商品选择
66
+     * @return [type] [description]
67
+     */
68
+    public function ajax_archives_list()
69
+    {
70
+        $assign_data = array();
71
+        $condition   = array();
72
+        // 获取到所有URL参数
73
+        $param  = input('param.');
74
+        $typeid = input('param.typeid/d');
75
+
76
+        // 应用搜索条件
77
+        foreach (['keywords', 'typeid'] as $key) {
78
+            if ($key == 'keywords' && !empty($param[$key])) {
79
+                $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
80
+            } else if ($key == 'typeid' && !empty($param[$key])) {
81
+                $typeid  = $param[$key];
82
+                $hasRow  = model('Arctype')->getHasChildren($typeid);
83
+                $typeids = get_arr_column($hasRow, 'id');
84
+                /*权限控制 by 小虎哥*/
85
+                $admin_info = session('admin_info');
86
+                if (0 < intval($admin_info['role_id'])) {
87
+                    $auth_role_info = $admin_info['auth_role_info'];
88
+                    if (!empty($auth_role_info)) {
89
+                        if (isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
90
+                            $condition['a.admin_id'] = $admin_info['admin_id'];
91
+                        }
92
+                        if (!empty($auth_role_info['permission']['arctype'])) {
93
+                            if (!empty($typeid)) {
94
+                                $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
95
+                            }
96
+                        }
97
+                    }
98
+                }
99
+                /*--end*/
100
+                $condition['a.typeid'] = array('IN', $typeids);
101
+            } else if (!empty($param[$key])) {
102
+                $condition['a.' . $key] = array('eq', $param[$key]);
103
+            }
104
+        }
105
+        // 审核通过
106
+        $condition['a.arcrank'] = array('gt', -1);
107
+        /*多语言*/
108
+        $condition['a.lang'] = array('eq', $this->admin_lang);
109
+        /*回收站数据不显示*/
110
+        $condition['a.is_del']  = array('eq', 0);
111
+        $channels               = 2;
112
+        $condition['a.channel'] = $channels;
113
+
114
+        $count = Db::name('archives')->alias('a')->where($condition)->count('aid');// 查询满足要求的总记录数
115
+        $Page  = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
116
+        $list  = Db::name('archives')
117
+            ->alias('a')
118
+            ->field("a.aid,a.litpic,a.title,b.typename,a.update_time")
119
+            ->where($condition)
120
+            ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
121
+            ->order('a.sort_order asc, a.aid desc')
122
+            ->limit($Page->firstRow . ',' . $Page->listRows)
123
+            ->getAllWithIndex('aid');
124
+
125
+
126
+        $show                 = $Page->show(); // 分页显示输出
127
+        $assign_data['page']  = $show; // 赋值分页输出
128
+        $assign_data['list']  = $list; // 赋值数据集
129
+        $assign_data['pager'] = $Page; // 赋值分页对象
130
+
131
+        /*允许发布文档列表的栏目*/
132
+        $allow_release_channel       = !empty($channels) ? explode(',', $channels) : [];
133
+        $assign_data['arctype_html'] = allow_release_arctype($typeid, $allow_release_channel);
134
+        /*--end*/
135
+
136
+        // 模型名称
137
+        $channeltype_ntitle = '文档';
138
+        if (!stristr($channels, ',')) {
139
+            $channeltype_row    = \think\Cache::get('extra_global_channeltype');
140
+            $channeltype_ntitle = $channeltype_row[$channels]['ntitle'];
141
+        }
142
+        $assign_data['channeltype_ntitle'] = $channeltype_ntitle;
143
+
144
+        $this->assign($assign_data);
145
+
146
+        return $this->fetch();
147
+    }
148
+
149
+    /**
150
+     * 添加限时折扣商品
151
+     */
152
+    public function add()
153
+    {
154
+        if (IS_POST) {
155
+            $post = input('post.');
156
+            if (is_array($post['discount_price'])) {
157
+                $post['is_sku'] = 1; // 多规格限时折扣商品
158
+                if (is_array($post['discount_stock'])) {
159
+                    $post['discount_stock_total'] = 0;
160
+                    foreach ($post['discount_stock'] as $k => $v) {
161
+                        $post['discount_stock_total'] += $v['spec_discount_stock'];
162
+                    }
163
+                }
164
+            }
165
+
166
+            $newData = [
167
+                'aid'           => $post['aid'],
168
+                'is_sku'        => isset($post['is_sku']) ? $post['is_sku'] : 0,
169
+                'discount_stock' => is_array($post['discount_stock']) ? $post['discount_stock_total'] : $post['discount_stock'],
170
+                'discount_price' => is_array($post['discount_price']) ? 0 : $post['discount_price'],
171
+                'virtual_sales' => $post['virtual_sales'],
172
+                'add_time'      => getTime(),
173
+                'update_time'   => getTime(),
174
+            ];
175
+
176
+            $insertId = Db::name('discount_goods')->insertGetId($newData);
177
+            if (false !== $insertId) {
178
+                if (isset($post['is_sku']) && 1 == $post['is_sku']) {
179
+                    model('ProductSpecValue')->ProducSpecValueEditSave($post);
180
+                }
181
+                adminLog('新增限时折扣商品:' . $insertId);
182
+                $this->success("操作成功", url('Discount/index'));
183
+            } else {
184
+                $this->error("操作失败", url('Discount/index'));
185
+            }
186
+            exit;
187
+        }
188
+
189
+        $id   = input('id/d');
190
+        $info = Db::name('archives')->field('aid,litpic,title,users_price')->where('aid', $id)->find();
191
+        // 获取规格数据信息
192
+        // 包含:SpecSelectName、HtmlTable、spec_mark_id_arr、preset_value
193
+        $assign_data = model('ProductSpecData')->GetDiscountProductSpecData($id);
194
+        // 商城配置
195
+        $shopConfig                = getUsersConfigData('shop');
196
+        $assign_data['shopConfig'] = $shopConfig;
197
+
198
+        $this->assign('info', $info);
199
+        $this->assign($assign_data);
200
+
201
+        return $this->fetch();
202
+    }
203
+
204
+    /**
205
+     * 编辑限时折扣商品
206
+     */
207
+    public function edit()
208
+    {
209
+        if (IS_POST) {
210
+            $post = input('post.');
211
+            if (is_array($post['discount_price'])) {
212
+                $post['is_sku'] = 1; // 多规格限时折扣商品
213
+                if (is_array($post['discount_stock'])) {
214
+                    $post['discount_stock_total'] = 0;
215
+                    foreach ($post['discount_stock'] as $k => $v) {
216
+                        $post['discount_stock_total'] += $v['spec_discount_stock'];
217
+                    }
218
+                }
219
+            }
220
+
221
+            $data = [
222
+                'is_sku'        => isset($post['is_sku']) ? $post['is_sku'] : 0,
223
+                'discount_stock' => is_array($post['discount_stock']) ? $post['discount_stock_total'] : $post['discount_stock'],
224
+                'discount_price' => is_array($post['discount_price']) ? 0 : $post['discount_price'],
225
+                'virtual_sales'         => $post['virtual_sales'],
226
+                'update_time'   => getTime(),
227
+            ];
228
+
229
+            $r = Db::name('discount_goods')->where('discount_gid', intval($post['discount_gid']))->update($data);
230
+            if (false !== $r) {
231
+                if (isset($post['is_sku']) && 1 == $post['is_sku']) {
232
+                    model('ProductSpecValue')->ProducSpecValueEditSave($post);
233
+                }
234
+                adminLog('编辑限时折扣商品:' . $post['discount_gid']);
235
+                $this->success("操作成功", url('Discount/index'));
236
+            } else {
237
+                $this->error("操作失败", url('Discount/index'));
238
+            }
239
+            exit;
240
+        }
241
+
242
+        $id   = input('id/d'); //指discount_gid
243
+        $info = Db::name('discount_goods')
244
+            ->alias('a')
245
+            ->field('a.*,b.litpic,b.title,b.users_price')
246
+            ->join('archives b', 'a.aid = b.aid')
247
+            ->where('a.discount_gid', $id)
248
+            ->find();
249
+        // 获取规格数据信息
250
+        // 包含:SpecSelectName、HtmlTable、spec_mark_id_arr、preset_value
251
+        $assign_data = model('ProductSpecData')->GetDiscountProductSpecData($info['aid']);
252
+        // 商城配置
253
+        $shopConfig                = getUsersConfigData('shop');
254
+        $assign_data['shopConfig'] = $shopConfig;
255
+
256
+        $this->assign('info', $info);
257
+        $this->assign($assign_data);
258
+
259
+        return $this->fetch();
260
+    }
261
+
262
+    /**
263
+     * 删除限时折扣商品
264
+     */
265
+    public function del()
266
+    {
267
+        if (IS_POST) {
268
+            $id_arr = input('del_id/a');
269
+            $id_arr = eyIntval($id_arr);
270
+            if (!empty($id_arr)) {
271
+                $aids = Db::name('discount_goods')
272
+                    ->where('discount_gid', 'IN', $id_arr)
273
+                    ->column('aid');
274
+
275
+                $r = Db::name('discount_goods')
276
+                    ->where('discount_gid', 'IN', $id_arr)
277
+                    ->delete();
278
+                if ($r) {
279
+                    Db::name('product_spec_value')
280
+                        ->where('aid', 'IN', $aids)
281
+                        ->update([
282
+                            'discount_price' => 0,
283
+                            'discount_stock' => 0,
284
+                            'is_discount'    => 0,
285
+                            'update_time'   => getTime()
286
+                        ]);
287
+                    adminLog('删除限时折扣商品,aid:' . implode(',', $aids));
288
+                    $this->success('删除成功');
289
+                } else {
290
+                    $this->error('删除失败');
291
+                }
292
+            } else {
293
+                $this->error('参数有误');
294
+            }
295
+        }
296
+        $this->error('非法访问');
297
+    }
298
+
299
+    /**
300
+     * 活动会场列表
301
+     * @return mixed
302
+     */
303
+    public function active_index()
304
+    {
305
+        $list = array();
306
+//        $keywords = input('keywords/s');
307
+//
308
+        $condition = array();
309
+//        if (!empty($keywords)) {
310
+//            $condition['title'] = array('LIKE', "%{$keywords}%");
311
+//        }
312
+
313
+        $Db    = Db::name('discount_active');
314
+        $count = $Db->where($condition)->count('active_id');// 查询满足要求的总记录数
315
+        $Page  = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
316
+        $list  = $Db
317
+            ->where($condition)
318
+            ->order('end_date desc')
319
+            ->limit($Page->firstRow . ',' . $Page->listRows)
320
+            ->getAllWithIndex('active_id');
321
+
322
+        $show = $Page->show();// 分页显示输出
323
+        $this->assign('page', $show);// 赋值分页输出
324
+        $this->assign('list', $list);// 赋值数据集
325
+        $this->assign('pager', $pager);// 赋值分页对象
326
+        return $this->fetch();
327
+    }
328
+
329
+    /**
330
+     * 添加活动场次
331
+     */
332
+    public function active_add()
333
+    {
334
+        if (IS_POST) {
335
+            $post = input('post.');
336
+            if (!empty($post['start_date'])) $post['start_date'] = strtotime($post['start_date']);
337
+            if (!empty($post['end_date'])) $post['end_date'] = strtotime($post['end_date']);
338
+            if (!empty($post['preheat_time'])) {
339
+                $post['preheat_time'] = strtotime($post['preheat_time']);
340
+                if ($post['preheat_time'] > $post['start_date']){
341
+                    $this->error('预热时间不能大于开始时间');
342
+                }
343
+            }
344
+
345
+            $post['add_time'] = getTime();
346
+            $post['update_time'] = getTime();
347
+            $insertId = Db::name('discount_active')->insertGetId($post);
348
+
349
+            if (false !== $insertId) {
350
+                $goodsData = [];
351
+                $discount_goods_id_arr = [];
352
+                foreach ($post['goods']['discount_gid'] as $k => $v) {
353
+                    if (!in_array($v,$discount_goods_id_arr)){
354
+                        $discount_goods_id_arr[] = $v;
355
+                        $goodsData[] = [
356
+                            'active_id'      => $insertId,
357
+                            'discount_goods_id' => $v,
358
+                            'aid'            => $post['goods']['aid'][$k],
359
+                            'add_time'       => getTime(),
360
+                            'update_time'    => getTime(),
361
+                        ];
362
+                    }
363
+
364
+                }
365
+
366
+                Db::name('discount_active_goods')->insertAll($goodsData);
367
+
368
+                adminLog('新增限时折扣活动:' . $insertId);
369
+                $this->success("操作成功", url('Discount/active_index'));
370
+            } else {
371
+                $this->error("操作失败", url('Discount/index'));
372
+            }
373
+            exit;
374
+        }
375
+        return $this->fetch();
376
+    }
377
+
378
+    /**
379
+     * 编辑活动
380
+     */
381
+    public function active_edit()
382
+    {
383
+        if(IS_POST){
384
+            $post = input('post.');
385
+            if (!empty($post['goods'])){
386
+                Db::name('discount_active_goods')
387
+                    ->where(['active_id'=>intval($post['active_id'])])
388
+                    ->delete();
389
+                $goodsData = [];
390
+                $discount_goods_id_arr = [];
391
+                foreach ($post['goods']['discount_gid'] as $k => $v) {
392
+                    if (!in_array($v,$discount_goods_id_arr)){
393
+                        $discount_goods_id_arr[] = $v;
394
+                        $goodsData[] = [
395
+                            'active_id'      => $post['active_id'],
396
+                            'discount_goods_id' => $v,
397
+                            'aid'            => $post['goods']['aid'][$k],
398
+                            'add_time'       => getTime(),
399
+                            'update_time'    => getTime(),
400
+                        ];
401
+                    }
402
+                }
403
+                $r = Db::name('discount_active_goods')->insertAll($goodsData);
404
+                if ($r){
405
+                    adminLog('编辑活动active_id:' . $post['active_id']);
406
+                    $this->success("操作成功", url('Discount/active_index',['id'=>$post['active_id']]));
407
+                } else {
408
+                    $this->error("操作失败", url('Discount/active_edit',['id'=>$post['active_id']]));
409
+                }
410
+            }
411
+        }
412
+        $id = input('id/d');
413
+        $info = Db::name('discount_active')->where('active_id',$id)->find();
414
+
415
+        $goods = Db::name('discount_active_goods')
416
+            ->alias('a')
417
+            ->field('a.*,b.litpic,b.title')
418
+            ->join('archives b','a.aid=b.aid')
419
+            ->where('a.active_id',$id)
420
+            ->select();
421
+
422
+        $this->assign('info',$info);
423
+        $this->assign('goods',$goods);
424
+        return $this->fetch();
425
+    }
426
+
427
+    /**
428
+     * 删除活动会场
429
+     */
430
+    public function active_del()
431
+    {
432
+        if (IS_POST) {
433
+            $id_arr = input('del_id/a');
434
+            $id_arr = eyIntval($id_arr);
435
+            if (!empty($id_arr)) {
436
+                $r = Db::name('discount_active')
437
+                    ->where('active_id', 'IN', $id_arr)
438
+                    ->delete();
439
+                if ($r) {
440
+                    Db::name('discount_active_goods')
441
+                        ->where('active_id', 'IN', $id_arr)
442
+                        ->delete();
443
+                    adminLog('删除活动,active_id:' . implode(',', $id_arr));
444
+                    $this->success('删除成功');
445
+                } else {
446
+                    $this->error('删除失败');
447
+                }
448
+            } else {
449
+                $this->error('参数有误');
450
+            }
451
+        }
452
+        $this->error('非法访问');
453
+    }
454
+
455
+    /**
456
+     * 限时折扣商品选择
457
+     * @return [type] [description]
458
+     */
459
+    public function goods_list()
460
+    {
461
+        $assign_data = array();
462
+        $condition   = array();
463
+        // 获取到所有URL参数
464
+        $param  = input('param.');
465
+        $typeid = input('param.typeid/d');
466
+
467
+        // 应用搜索条件
468
+        foreach (['keywords', 'typeid'] as $key) {
469
+            if ($key == 'keywords' && !empty($param[$key])) {
470
+                $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
471
+            } else if ($key == 'typeid' && !empty($param[$key])) {
472
+                $typeid  = $param[$key];
473
+                $hasRow  = model('Arctype')->getHasChildren($typeid);
474
+                $typeids = get_arr_column($hasRow, 'id');
475
+                /*权限控制 by 小虎哥*/
476
+                $admin_info = session('admin_info');
477
+                if (0 < intval($admin_info['role_id'])) {
478
+                    $auth_role_info = $admin_info['auth_role_info'];
479
+                    if (!empty($auth_role_info)) {
480
+                        if (isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
481
+                            $condition['a.admin_id'] = $admin_info['admin_id'];
482
+                        }
483
+                        if (!empty($auth_role_info['permission']['arctype'])) {
484
+                            if (!empty($typeid)) {
485
+                                $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
486
+                            }
487
+                        }
488
+                    }
489
+                }
490
+                /*--end*/
491
+                $condition['a.typeid'] = array('IN', $typeids);
492
+            }
493
+        }
494
+        /*回收站数据不显示*/
495
+        $where['b.is_del'] = 0;
496
+        $where['b.status'] = 1;
497
+
498
+        $count = Db::name('discount_goods')->alias('b')->where($where)->count('aid');// 查询满足要求的总记录数
499
+        $Page  = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
500
+        $list  = Db::name('discount_goods')
501
+            ->alias('b')
502
+            ->field("a.litpic,a.title,b.discount_gid,b.aid,b.update_time,b.discount_stock")
503
+            ->where($where)
504
+            ->where($condition)
505
+            ->join('archives a', 'a.aid = b.aid', 'LEFT')
506
+            ->join('arctype c', 'a.typeid = c.id', 'LEFT')
507
+            ->order('b.sort_order asc, b.discount_gid desc')
508
+            ->limit($Page->firstRow . ',' . $Page->listRows)
509
+            ->getAllWithIndex('aid');
510
+        if ($list) {
511
+            foreach ($list as $key => $val) {
512
+                $val['litpic']             = get_default_pic($val['litpic']);
513
+                $json_encode_params        = [
514
+                    'discount_gid' => $val['discount_gid'],
515
+                    'aid'            => $val['aid'],
516
+                    'title'          => $val['title'],
517
+                    'litpic'         => $val['litpic'],
518
+                ];
519
+                $val['json_encode_params'] = json_encode($json_encode_params, JSON_UNESCAPED_SLASHES);
520
+                $list[$key]                = $val;
521
+            }
522
+        }
523
+
524
+        $show                 = $Page->show(); // 分页显示输出
525
+        $assign_data['page']  = $show; // 赋值分页输出
526
+        $assign_data['list']  = $list; // 赋值数据集
527
+        $assign_data['pager'] = $Page; // 赋值分页对象
528
+
529
+        $channels = 2;
530
+        /*允许发布文档列表的栏目*/
531
+        $allow_release_channel       = !empty($channels) ? explode(',', $channels) : [];
532
+        $assign_data['arctype_html'] = allow_release_arctype($typeid, $allow_release_channel);
533
+        /*--end*/
534
+
535
+        $this->assign($assign_data);
536
+
537
+        return $this->fetch();
538
+    }
539
+
540
+}

+ 26
- 0
application/admin/controller/DiyExtend.php View File

@@ -0,0 +1,26 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use think\Db;
16
+use think\Page;
17
+
18
+/**
19
+ * 用户自定义扩展php文件
20
+ */
21
+class DiyExtend extends Base {
22
+    
23
+    public function _initialize() {
24
+        parent::_initialize();
25
+    }
26
+}

+ 1026
- 0
application/admin/controller/Download.php
File diff suppressed because it is too large
View File


+ 9
- 0
application/admin/controller/Encodes.php
File diff suppressed because it is too large
View File


+ 1799
- 0
application/admin/controller/Field.php
File diff suppressed because it is too large
View File


+ 266
- 0
application/admin/controller/Filemanager.php View File

@@ -0,0 +1,266 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use app\admin\controller\Base;
16
+use think\Controller;
17
+use think\Db;
18
+use app\admin\logic\FilemanagerLogic;
19
+
20
+class Filemanager extends Base
21
+{
22
+    public $filemanagerLogic;
23
+    public $baseDir = '';
24
+    public $maxDir = '';
25
+    public $globalTpCache = array();
26
+
27
+    public function _initialize() {
28
+        parent::_initialize();
29
+        $this->filemanagerLogic = new FilemanagerLogic(); 
30
+        $this->globalTpCache = $this->filemanagerLogic->globalTpCache;
31
+        $this->baseDir = $this->filemanagerLogic->baseDir; // 服务器站点根目录绝对路径
32
+        $this->maxDir = $this->filemanagerLogic->maxDir; // 默认文件管理的最大级别目录
33
+    }
34
+
35
+    public function index()
36
+    {
37
+        // 获取到所有GET参数
38
+        $param = input('param.', '', null);
39
+        $activepath = input('param.activepath', '', null);
40
+        $activepath = $this->filemanagerLogic->replace_path($activepath, ':', true);
41
+
42
+        /*当前目录路径*/
43
+        $activepath = !empty($activepath) ? $activepath : $this->maxDir;
44
+        $tmp_max_dir = preg_replace("#\/#i", "\/", $this->maxDir);
45
+        if (!preg_match("#^".$tmp_max_dir."#i", $activepath)) {
46
+            $activepath = $this->maxDir;
47
+        }
48
+        /*--end*/
49
+
50
+        $inpath = "";
51
+        $activepath = str_replace("..", "", $activepath);
52
+        $activepath = preg_replace("#^\/{1,}#", "/", $activepath); // 多个斜杆替换为单个斜杆
53
+        if($activepath == "/") $activepath = "";
54
+
55
+        if(empty($activepath)) {
56
+            $inpath = $this->baseDir.$this->maxDir;
57
+        } else {
58
+            $inpath = $this->baseDir.$activepath;
59
+        }
60
+
61
+        $list = $this->filemanagerLogic->getDirFile($inpath, $activepath);
62
+        $assign_data['list'] = $list;
63
+
64
+        /*文件操作*/
65
+        $assign_data['replaceImgOpArr'] = $this->filemanagerLogic->replaceImgOpArr;
66
+        $assign_data['editOpArr'] = $this->filemanagerLogic->editOpArr;
67
+        $assign_data['renameOpArr'] = $this->filemanagerLogic->renameOpArr;
68
+        $assign_data['delOpArr'] = $this->filemanagerLogic->delOpArr;
69
+        $assign_data['moveOpArr'] = $this->filemanagerLogic->moveOpArr;
70
+        /*--end*/
71
+
72
+        $assign_data['activepath'] = $activepath;
73
+
74
+        $this->assign($assign_data);
75
+        return $this->fetch();
76
+    }
77
+
78
+
79
+    /**
80
+     * 替换图片
81
+     */
82
+    public function replace_img()
83
+    {
84
+        if (IS_POST) {
85
+            $post = input('post.', '', null);
86
+            $activepath = !empty($post['activepath']) ? trim($post['activepath']) : '';
87
+            if (empty($activepath)) {
88
+                $this->error('参数有误');
89
+                exit;
90
+            }
91
+
92
+            $file = request()->file('upfile');
93
+            if (empty($file)) {
94
+                $this->error('请选择上传图片!');
95
+                exit;
96
+            } else {
97
+                $image_type = tpCache('global.image_type');
98
+                $fileExt = !empty($image_type) ? str_replace('|', ',', $image_type) : config('global.image_ext');
99
+                $image_upload_limit_size = intval(tpCache('global.file_size') * 1024 * 1024);
100
+                $result = $this->validate(
101
+                    ['file' => $file], 
102
+                    ['file'=>'image|fileSize:'.$image_upload_limit_size.'|fileExt:'.$fileExt],
103
+                    ['file.image' => '上传文件必须为图片','file.fileSize' => '上传文件过大','file.fileExt'=>'上传文件后缀名必须为'.$fileExt]
104
+                );
105
+                if (true !== $result || empty($file)) {
106
+                    $this->error($result);
107
+                    exit;
108
+                }
109
+            }
110
+
111
+            $res = $this->filemanagerLogic->upload('upfile', $activepath, $post['filename'], 'image');
112
+            if ($res['code'] == 1) {
113
+                $this->success('操作成功!', url('Filemanager/index', array('activepath'=>$this->filemanagerLogic->replace_path($activepath, ':', false))));
114
+            } else {
115
+                $this->error($res['msg'], url('Filemanager/index', array('activepath'=>$this->filemanagerLogic->replace_path($activepath, ':', false))));
116
+            }
117
+        }
118
+
119
+        $filename = input('param.filename/s', '', null);
120
+
121
+        $activepath = input('param.activepath/s', '', null);
122
+        $activepath = $this->filemanagerLogic->replace_path($activepath, ':', true);
123
+        if ($activepath == "") $activepathname = "根目录";
124
+        else $activepathname = $activepath;
125
+
126
+        $info = array(
127
+            'activepath'    => $activepath,
128
+            'activepathname'    => $activepathname,
129
+            'filename'  => $filename,
130
+        );
131
+        $this->assign('info', $info);
132
+        return $this->fetch();
133
+    }
134
+
135
+    /**
136
+     * 编辑
137
+     */
138
+    public function edit()
139
+    {
140
+        if (IS_POST) {
141
+            $post = input('post.', '', null);
142
+            $content = input('post.content', '', null);
143
+            $filename = !empty($post['filename']) ? trim($post['filename']) : '';
144
+            $content = !empty($content) ? $content : '';
145
+            $activepath = !empty($post['activepath']) ? trim($post['activepath']) : '';
146
+
147
+            if (empty($filename) || empty($activepath)) {
148
+                $this->error('参数有误');
149
+                exit;
150
+            }
151
+
152
+            $r = $this->filemanagerLogic->editFile($filename, $activepath, $content);
153
+            if ($r === true) {
154
+                $this->success('操作成功!', url('Filemanager/index', array('activepath'=>$this->filemanagerLogic->replace_path($activepath, ':', false))));
155
+                exit;
156
+            } else {
157
+                $this->error($r, null, [], 8);
158
+                exit;
159
+            }
160
+        }
161
+
162
+        $activepath = input('param.activepath/s', '', null);
163
+        $activepath = $this->filemanagerLogic->replace_path($activepath, ':', true);
164
+
165
+        $filename = input('param.filename/s', '', null);
166
+
167
+        $activepath = str_replace("..", "", $activepath);
168
+        $filename = str_replace("..", "", $filename);
169
+        $path_parts  = pathinfo($filename);
170
+        $path_parts['extension'] = strtolower($path_parts['extension']);
171
+
172
+        /*不允许越过指定最大级目录的文件编辑*/
173
+        $tmp_max_dir = preg_replace("#\/#i", "\/", $this->filemanagerLogic->maxDir);
174
+        if (!preg_match("#^".$tmp_max_dir."#i", $activepath)) {
175
+            $this->error('没有操作权限!');
176
+            exit;
177
+        }
178
+        /*--end*/
179
+        
180
+        /*允许编辑的文件类型*/
181
+        if (!in_array($path_parts['extension'], $this->filemanagerLogic->editExt)) {
182
+            $this->error('只允许操作文件类型如下:'.implode('|', $this->filemanagerLogic->editExt));
183
+            exit;
184
+        }
185
+        /*--end*/
186
+
187
+        /*读取文件内容*/
188
+        $file = $this->baseDir."$activepath/$filename";
189
+        $content = "";
190
+        if(is_file($file))
191
+        {
192
+            $filesize = filesize($file);
193
+            if (0 < $filesize) {
194
+                $fp = fopen($file, "r");
195
+                $content = fread($fp, $filesize);
196
+                fclose($fp);
197
+                if ('htm' == $path_parts['extension']) {
198
+                    $content = htmlspecialchars($content, ENT_QUOTES);
199
+                    foreach ($this->filemanagerLogic->disableFuns as $key => $val) {
200
+                        $val_new = msubstr($val, 0, 1).'-'.msubstr($val, 1);
201
+                        $content = preg_replace("/(@)?".$val."(\s*)\(/i", "{$val_new}(", $content);
202
+                    }
203
+                }
204
+            }
205
+        }
206
+        /*--end*/
207
+
208
+        if($path_parts['extension'] == 'js'){
209
+            $extension = 'text/javascript';
210
+        } else if($path_parts['extension'] == 'css'){
211
+            $extension = 'text/css';
212
+        } else {
213
+            $extension = 'text/html';
214
+        }
215
+
216
+        $info = array(
217
+            'filename'  => $filename,
218
+            'activepath'=> $activepath,
219
+            'extension' => $extension,
220
+            'content'   => $content,
221
+        );
222
+        $this->assign('info', $info);
223
+        return $this->fetch();
224
+    }
225
+
226
+    /**
227
+     * 新建文件
228
+     */
229
+    public function newfile()
230
+    {
231
+        if (IS_POST) {
232
+            $post = input('post.', '', null);
233
+            $content = input('post.content', '', null);
234
+            $filename = !empty($post['filename']) ? trim($post['filename']) : '';
235
+            $content = !empty($content) ? $content : '';
236
+            $activepath = !empty($post['activepath']) ? trim($post['activepath']) : '';
237
+
238
+            if (empty($filename) || empty($activepath)) {
239
+                $this->error('参数有误');
240
+                exit;
241
+            }
242
+
243
+            $r = $this->filemanagerLogic->editFile($filename, $activepath, $content);
244
+            if ($r === true) {
245
+                $this->success('操作成功!', url('Filemanager/index', array('activepath'=>$this->filemanagerLogic->replace_path($activepath, ':', false))));
246
+                exit;
247
+            } else {
248
+                $this->error($r, null, [], 8);
249
+                exit;
250
+            }
251
+        }
252
+
253
+        $activepath = input('param.activepath/s', '', null);
254
+        $activepath = $this->filemanagerLogic->replace_path($activepath, ':', true);
255
+        $filename = 'newfile.htm';
256
+        $content = "";
257
+        $info = array(
258
+            'filename'  => $filename,
259
+            'activepath'=> $activepath,
260
+            'content'   => $content,
261
+            'extension' => 'text/html',
262
+        );
263
+        $this->assign('info', $info);
264
+        return $this->fetch();
265
+    }
266
+}

+ 239
- 0
application/admin/controller/Foreign.php View File

@@ -0,0 +1,239 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+namespace app\admin\controller;
14
+
15
+use think\Db;
16
+use think\Page;
17
+use think\Cache;
18
+use app\admin\logic\ForeignLogic;
19
+
20
+class Foreign extends Base {
21
+
22
+    /**
23
+     * 实例化模型
24
+     */
25
+    private $logic;
26
+
27
+    /**
28
+     * 构造方法
29
+     */
30
+    public function __construct() {
31
+        parent::__construct();
32
+        $this->logic = new ForeignLogic;
33
+        $functionLogic = new \app\common\logic\FunctionLogic;
34
+        $functionLogic->validate_authorfile(1);
35
+    }
36
+
37
+    /**
38
+     * 基本设置
39
+     * @return [type] [description]
40
+     */
41
+    public function index()
42
+    {
43
+        $assign_data = [];
44
+        // 基本设置
45
+        $foreignData = tpSetting('foreign', [], 'cn');
46
+        // 外贸助手插件的配置同步到内置里
47
+        $admin_logic_1693909371 = tpSetting('syn.admin_logic_1693909371', [], 'cn');
48
+        if (empty($admin_logic_1693909371)) {
49
+            if (is_dir('./weapp/Waimao/')) {
50
+                $row = Db::name('weapp')->where(['code'=>'Waimao'])->find();
51
+                $row['data'] = !empty($$row['data']) ? json_decode($$row['data'], true) : [];
52
+                $foreignData['foreign_is_status'] = (!empty($row['status']) && 1 == $row['status']) ? 1 : 0;
53
+                $foreignData['foreign_clear_htmlfilename'] = empty($row['data']['clear_htmlfilename']) ? 0 : $row['data']['clear_htmlfilename'];
54
+                tpSetting('foreign', $foreignData, 'cn');
55
+            }
56
+            tpSetting('syn', ['admin_logic_1693909371'=>1], 'cn');
57
+        }
58
+        $assign_data['foreignData'] = empty($foreignData) ? [] : $foreignData;
59
+        $this->assign($assign_data);
60
+        return $this->fetch();
61
+    }
62
+
63
+    /**
64
+     * 保存基本设置
65
+     * @return [type] [description]
66
+     */
67
+    public function conf_save()
68
+    {
69
+        if (IS_POST) {
70
+            $post = input('post.');
71
+            if (!empty($this->globalConfig['seo_pseudo']) && 1 == $this->globalConfig['seo_pseudo']) {
72
+                $post['seo_titleurl_format'] = 0;
73
+                $post['foreign_clear_htmlfilename'] = 0;
74
+            }
75
+            $seoData = [
76
+                'seo_titleurl_format' => intval($post['seo_titleurl_format']),
77
+            ];
78
+            tpCache('seo', $seoData);
79
+
80
+            $basicData = [
81
+                'basic_indexname' => $post['basic_indexname'],
82
+            ];
83
+            tpCache('basic', $basicData);
84
+
85
+            // 清空文档的自定义文件名
86
+            if (empty($post['seo_titleurl_format'])) {
87
+                if (!empty($post['foreign_clear_htmlfilename'])) {
88
+                    Db::name('archives')->where(['aid'=>['gt', 0]])->update(['htmlfilename'=>'']);
89
+                }
90
+            }
91
+
92
+            // 基本设置
93
+            $foreignData = tpSetting('foreign', [], 'cn');
94
+            $foreignData['foreign_is_status'] = intval($post['foreign_is_status']);
95
+            $foreignData['foreign_clear_htmlfilename'] = intval($post['foreign_clear_htmlfilename']);
96
+            tpSetting('foreign', $foreignData, 'cn');
97
+
98
+            // 插件配置
99
+            if (is_dir('./weapp/Waimao/')) {
100
+                $weappData = Db::name('weapp')->where(['code'=>'Waimao'])->value('data');
101
+                $weappData = !empty($weappData) ? json_decode($weappData, true) : [];
102
+                $weappData['clear_htmlfilename'] = intval($post['foreign_clear_htmlfilename']);
103
+                $saveData = [
104
+                    'data' => json_encode($weappData),
105
+                    'update_time' => getTime(),
106
+                ];
107
+                Db::name('weapp')->where(['code'=>'Waimao'])->update($saveData);
108
+            }
109
+
110
+            $this->success("操作成功");
111
+        }
112
+        $this->error("操作失败");
113
+    }
114
+
115
+    /**
116
+     * 批量更新文档URL
117
+     */
118
+    // public function htmlfilename_index()
119
+    // {
120
+    //     $foreignData = tpSetting('foreign', [], 'cn');
121
+    //     if (empty($foreignData['foreign_is_status'])) {
122
+    //         $this->error('尚未启用外贸助手功能', url('Foreign/index'));
123
+    //     }
124
+    //     $seo_titleurl_format = empty($this->globalConfig['seo_titleurl_format']) ? 0 : $this->globalConfig['seo_titleurl_format'];
125
+    //     if (empty($seo_titleurl_format)) {
126
+    //         $this->error('文档URL尚未开启外贸格式', url('Foreign/index'));
127
+    //     }
128
+
129
+    //     // 基本设置
130
+    //     $assign_data = [];
131
+    //     $foreignData = tpSetting('foreign', [], 'cn');
132
+    //     $assign_data['foreignData'] = empty($foreignData) ? [] : $foreignData;
133
+    //     $this->assign($assign_data);
134
+
135
+    //     return $this->fetch();
136
+    // }
137
+
138
+    /**
139
+     * 执行 - 批量更新文档URL
140
+     */
141
+    public function htmlfilename_handel()
142
+    {
143
+        @ini_set('memory_limit', '-1');
144
+        function_exists('set_time_limit') && set_time_limit(0);
145
+
146
+        if (!empty($this->globalConfig['seo_pseudo']) && 1 == $this->globalConfig['seo_pseudo']) {
147
+            $this->error("动态模式下不支持外贸链接格式");
148
+        }
149
+
150
+        if (IS_POST) {
151
+            $foreignData = tpSetting('foreign', [], 'cn');
152
+            if (empty($foreignData['foreign_is_status'])) {
153
+                $this->error('外贸助手已关闭', url('Foreign/index'));
154
+            }
155
+            $seo_titleurl_format = empty($this->globalConfig['seo_titleurl_format']) ? 0 : $this->globalConfig['seo_titleurl_format'];
156
+            if (empty($seo_titleurl_format)) {
157
+                $this->error('请勾选文档URL格式为外贸链接', url('Foreign/index'));
158
+            }
159
+
160
+            $foreign_htmlfilename_mode = input('param.foreign_htmlfilename_mode/d');
161
+            if (!empty($foreign_htmlfilename_mode)) {
162
+                Db::name('archives')->where(['aid'=>['gt', 0]])->update(['htmlfilename'=>'']);
163
+                $this->success('', null, ['achievepage'=>0,'allpagetotal'=>0,'pagetotal'=>0]);
164
+            } else {
165
+                $achievepage = input("param.achieve/d", 0); // 已完成文档数
166
+                $data = $this->logic->handelUpdateArticle($foreign_htmlfilename_mode, $achievepage);
167
+                $this->success($data[0], null, $data[1]);
168
+            }
169
+        }
170
+
171
+        $foreign_htmlfilename_mode = input('param.foreign_htmlfilename_mode/d');
172
+        $this->assign('foreign_htmlfilename_mode', $foreign_htmlfilename_mode);
173
+
174
+        // 批量更新URL的配置
175
+        $foreignData = tpSetting('foreign', [], 'cn');
176
+        $foreignData['foreign_htmlfilename_mode'] = $foreign_htmlfilename_mode;
177
+        tpSetting('foreign', $foreignData, 'cn');
178
+
179
+        return $this->fetch();
180
+    }
181
+
182
+    /**
183
+     * 清除数据缓存+页面缓存
184
+     * @return [type] [description]
185
+     */
186
+    public function clear_cache_htmlfilename()
187
+    {
188
+        Cache::clear();
189
+        delFile(RUNTIME_PATH);
190
+    }
191
+
192
+    /**
193
+     * 语言包变量
194
+     * @return [type] [description]
195
+     */
196
+    public function official_pack_index()
197
+    {
198
+        $foreign_is_status = tpSetting('foreign.foreign_is_status', '', 'cn');
199
+        if (empty($foreign_is_status)) {
200
+            $this->error('先启用外贸助手并保存');
201
+        }
202
+        $list = [];
203
+        $packList = Db::name('foreign_pack')->field('id,type,name,value,lang')->order('type asc, lang asc, id asc')->select();
204
+        foreach ($packList as $key => $val) {
205
+            $list[$val['type']][$val['name']][$val['lang']] = $val;
206
+        }
207
+        $this->assign('list', $list);
208
+        return $this->fetch();
209
+    }
210
+
211
+    /**
212
+     * 保存语言包变量
213
+     * @return [type] [description]
214
+     */
215
+    public function official_pack_save()
216
+    {
217
+        if (IS_POST) {
218
+            $post = input('post.');
219
+            $data = empty($post['data']) ? [] : $post['data'];
220
+            $saveData = [];
221
+            foreach ($data as $key => $val) {
222
+                $saveData[] = [
223
+                    'id' => intval($key),
224
+                    'value' => htmlspecialchars_decode($val),
225
+                    'update_time' => getTime(),
226
+                ];
227
+            }
228
+            $r = true;
229
+            if (!empty($saveData)) {
230
+                $r = model('ForeignPack')->saveAll($saveData);
231
+            }
232
+            if ($r !== false) {
233
+                Cache::clear('foreign_pack');
234
+                $this->success("操作成功");
235
+            }
236
+        }
237
+        $this->error("操作失败");
238
+    }
239
+}

+ 1434
- 0
application/admin/controller/Form.php
File diff suppressed because it is too large
View File


+ 937
- 0
application/admin/controller/Guestbook.php View File

@@ -0,0 +1,937 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use app\common\logic\ArctypeLogic;
19
+
20
+class Guestbook extends Base
21
+{
22
+    // 模型标识
23
+    public $nid = 'guestbook';
24
+    // 模型ID
25
+    public $channeltype = '';
26
+    // 表单类型
27
+    public $attrInputTypeArr = array();
28
+
29
+    public function _initialize()
30
+    {
31
+        parent::_initialize();
32
+        $channeltype_list       = config('global.channeltype_list');
33
+        $this->channeltype      = $channeltype_list[$this->nid];
34
+        $this->attrInputTypeArr = config('global.guestbook_attr_input_type');
35
+    }
36
+
37
+    /**
38
+     * 留言列表 - 仅是栏目关联的留言
39
+     */
40
+    public function index()
41
+    {
42
+        $assign_data = array();
43
+        $condition   = array();
44
+        // 获取到所有GET参数
45
+        $get    = input('get.');
46
+        $typeid = input('typeid/d');
47
+        $begin    = strtotime(input('param.add_time_begin/s'));
48
+        $end    = input('param.add_time_end/s');
49
+        !empty($end) && $end .= ' 23:59:59';
50
+        $end    = strtotime($end);
51
+
52
+        // 应用搜索条件
53
+        foreach (['keywords', 'typeid'] as $key) {
54
+            if (isset($get[$key]) && $get[$key] !== '') {
55
+                if ($key == 'keywords') {
56
+                    $attr_row           = Db::name('guestbook_attr')->field('aid')->where(array('attr_value' => array('LIKE', "%{$get[$key]}%"),'form_type'=>0))->group('aid')->getAllWithIndex('aid');
57
+                    $aids               = array_keys($attr_row);
58
+                    $condition['a.aid'] = array('IN', $aids);
59
+                } else if ($key == 'typeid') {
60
+                    $condition['a.typeid'] = array('eq', $get[$key]);
61
+                } else {
62
+                    $condition['a.' . $key] = array('eq', $get[$key]);
63
+                }
64
+            }
65
+        }
66
+
67
+        // 时间检索
68
+        if ($begin > 0 && $end > 0) {
69
+            $condition['a.add_time'] = array('between',"$begin,$end");
70
+        } else if ($begin > 0) {
71
+            $condition['a.add_time'] = array('egt', $begin);
72
+        } else if ($end > 0) {
73
+            $condition['a.add_time'] = array('elt', $end);
74
+        }
75
+
76
+        if (empty($typeid)) {
77
+            /*权限控制 by 小虎哥*/
78
+            $admin_info = session('admin_info');
79
+            if (0 < intval($admin_info['role_id'])) {
80
+                $auth_role_info = $admin_info['auth_role_info'];
81
+                if(! empty($auth_role_info)){
82
+                    $is_notaccess = false;
83
+                    $permission_arctype = !empty($auth_role_info['permission']['arctype']) ? $auth_role_info['permission']['arctype'] : [];
84
+                    if(! empty($permission_arctype)){
85
+                        $typeids_tmp = Db::name('arctype')->where(['current_channel'=>8,'lang'=>$this->admin_lang])->cache(true, EYOUCMS_CACHE_TIME, 'arctype')->column('id');
86
+                        $typeids_tmp = !empty($typeids_tmp) ? $typeids_tmp : [];
87
+                        $typeids_tmp2 = array_intersect($typeids_tmp, $auth_role_info['permission']['arctype']);
88
+                        if (!empty($typeids_tmp2)) {
89
+                            $condition['a.typeid'] = ['IN', $typeids_tmp2];
90
+                            $is_notaccess = true;
91
+                        }
92
+                    }
93
+                    if (false === $is_notaccess) {
94
+                        $this->error('您没有操作权限,请联系超级管理员分配权限');
95
+                    }
96
+                }
97
+            }
98
+            /*--end*/
99
+        }
100
+
101
+        $condition['a.form_type'] = 0;
102
+        // 多语言
103
+        $condition['a.lang'] = array('eq', $this->admin_lang);
104
+
105
+        /**
106
+         * 数据查询,搜索出主键ID的值
107
+         */
108
+        $count = Db::name('guestbook')->alias('a')->where($condition)->count('aid');// 查询满足要求的总记录数
109
+        $Page  = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
110
+        $list  = Db::name('guestbook')
111
+            ->field("b.*, a.*")
112
+            ->alias('a')
113
+            ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
114
+            ->where($condition)
115
+            ->order('a.is_read asc, a.add_time desc')
116
+            ->limit($Page->firstRow . ',' . $Page->listRows)
117
+            ->getAllWithIndex('aid');
118
+
119
+        /**
120
+         * 完善数据集信息
121
+         * 在数据量大的情况下,经过优化的搜索逻辑,先搜索出主键ID,再通过ID将其他信息补充完整;
122
+         */
123
+        $typeids = [];
124
+        if ($list) {
125
+            $where = [
126
+                'b.aid'     => ['IN', array_keys($list)],
127
+                'a.is_showlist' => 1,
128
+                'a.lang'    => $this->admin_lang,
129
+                'a.is_del'  => 0,
130
+            ];
131
+            $row       = Db::name('guestbook_attribute')
132
+                ->field('a.attr_name, a.typeid, b.attr_value, b.aid, b.attr_id,a.attr_input_type')
133
+                ->alias('a')
134
+                ->join('__GUESTBOOK_ATTR__ b', 'b.attr_id = a.attr_id', 'LEFT')
135
+                ->where($where)
136
+                ->order('b.aid desc, a.sort_order asc, a.attr_id asc')
137
+                ->getAllWithIndex();
138
+            $attr_list = array();
139
+            foreach ($row as $key => $val) {
140
+                $typeids[] = $val['typeid'];
141
+                if (9 == $val['attr_input_type']){
142
+                    //如果是区域类型,转换名称
143
+                    $val['attr_value'] = Db::name('region')->where('id','in',$val['attr_value'])->column('name');
144
+                    $val['attr_value'] = implode('',$val['attr_value']);
145
+                }else if(10 == $val['attr_input_type']){
146
+                    $val['attr_value'] = date('Y-m-d H:i:s',$val['attr_value']);
147
+                } else if(11 == $val['attr_input_type']) {
148
+                    $attrValueArr = !empty($val['attr_value']) ? explode(',', $val['attr_value']) : [];
149
+                    $val['attr_value'] = '';
150
+                    foreach ($attrValueArr as $_k => $_v) {
151
+                        if ($_k >= 2) {
152
+                            break;
153
+                        }
154
+                        if (preg_match('/(\.('.tpCache('global.image_type').'))$/i', $_v)) {
155
+                            if (!stristr($_v, '|')) {
156
+                                $_v = handle_subdir_pic($_v);
157
+                                $val['attr_value'] .= "<img src='{$_v}' width='60' height='60' style='float: unset; cursor: pointer;margin: 0px 3px;' onclick=\"Images('{$_v}', 650, 350);\" />";
158
+                            }
159
+                        } elseif (preg_match('/(\.('.tpCache('global.file_type').'))$/i', $_v)) {
160
+                            if (!stristr($_v, '|')) {
161
+                                $_v = handle_subdir_pic($_v);
162
+                                $val['attr_value'] .= "<a href='{$_v}' download='".time()."'><img src=\"".ROOT_DIR."/public/static/common/images/file.png\" alt=\"\" style=\"width: 16px; height: 16px;\">文件下载</a>";
163
+                            }
164
+                        }
165
+                    }
166
+                }
167
+                if (preg_match('/(\.('.tpCache('global.image_type').'))$/i', $val['attr_value'])) {
168
+                    if (!stristr($val['attr_value'], '|')) {
169
+                        $val['attr_value'] = handle_subdir_pic($val['attr_value']);
170
+                        $val['attr_value'] = "<img src='{$val['attr_value']}' width='60' height='60' style='float: unset;cursor: pointer;' onclick=\"Images('{$val['attr_value']}', 650, 350);\" />";
171
+                    }
172
+                }elseif (preg_match('/(\.('.tpCache('global.file_type').'))$/i', $val['attr_value'])){
173
+                    if (!stristr($val['attr_value'], '|')) {
174
+                        $val['attr_value'] = handle_subdir_pic($val['attr_value']);
175
+                        $download_name = preg_replace('/^(.*)\/([^\/]+)\.(\w+)$/i', '${2}', $val['attr_value']);
176
+                        $val['attr_value'] = "<a href='{$val['attr_value']}' download='".$download_name."'><img src=\"".ROOT_DIR."/public/static/common/images/file.png\" alt=\"\" style=\"width:16px;height:16px;float:unset;\">&nbsp;点击下载</a>";
177
+                    }
178
+                } else {
179
+                    $val['attr_value'] = str_replace(PHP_EOL, ' | ', $val['attr_value']);
180
+                }
181
+                $attr_list[$val['aid']][] = $val;
182
+            }
183
+            foreach ($list as $key => $val) {
184
+                $list[$key]['attr_list'] = isset($attr_list[$val['aid']]) ? $attr_list[$val['aid']] : array();
185
+            }
186
+        }
187
+        $tab_list = Db::name('guestbook_attribute')->where([
188
+                'typeid' => ['IN', $typeids],
189
+                'form_type'       => 0,
190
+                'is_showlist' => 1,
191
+                'lang'   => $this->admin_lang,
192
+                'is_del'    => 0,
193
+            ])->order('typeid asc, sort_order asc, attr_id asc')->select();
194
+        $tab_list = group_same_key($tab_list, 'typeid');
195
+        if (!empty($typeid)) {
196
+            $tab_list = empty($tab_list[$typeid]) ? [] : $tab_list[$typeid];
197
+        }
198
+        $assign_data['tab_list']    = $tab_list;
199
+        $show                    = $Page->show(); // 分页显示输出
200
+        $assign_data['page']     = $show; // 赋值分页输出
201
+        $assign_data['list']     = $list; // 赋值数据集
202
+        $assign_data['pager']    = $Page; // 赋值分页对象
203
+
204
+        // 栏目ID
205
+        $assign_data['typeid'] = $typeid; // 栏目ID
206
+        /*当前栏目信息*/
207
+        $arctype_info = array();
208
+        if ($typeid > 0) {
209
+            $arctype_info = Db::name('arctype')->field('typename')->find($typeid);
210
+        }
211
+        $assign_data['arctype_info'] = $arctype_info;
212
+        /*--end*/
213
+
214
+        /*选项卡*/
215
+        $tab                = input('param.tab/d', 3);
216
+        $assign_data['tab'] = $tab;
217
+        /*--end*/
218
+
219
+        $this->assign($assign_data);
220
+        return $this->fetch();
221
+    }
222
+
223
+    /**
224
+     * 删除
225
+     */
226
+    public function del()
227
+    {
228
+        $id_arr = input('del_id/a');
229
+        $id_arr = eyIntval($id_arr);
230
+        $form_type = input('param.form_type/d', 0);
231
+        if (!empty($id_arr)) {
232
+            $r = Db::name('guestbook')->where([
233
+                'aid'  => ['IN', $id_arr],
234
+                'form_type' => $form_type,
235
+                'lang' => $this->admin_lang,
236
+            ])->delete();
237
+            if ($r !== false) {
238
+                // ---------后置操作
239
+                model('Guestbook')->afterDel($id_arr);
240
+                // ---------end
241
+                adminLog('删除留言-id:' . implode(',', $id_arr));
242
+                $this->success('删除成功');
243
+            }
244
+        }
245
+        $this->error('删除失败');
246
+    }
247
+
248
+    //留言表单表单列表
249
+    public function attribute_index()
250
+    {
251
+        $assign_data = array();
252
+        $condition = array();
253
+        $get = input('get.');
254
+        $typeid = input('typeid/d');
255
+        foreach (['keywords','typeid'] as $key) {
256
+            if (isset($get[$key]) && $get[$key] !== '') {
257
+                if ($key == 'keywords') {
258
+                    $condition['a.attr_name'] = array('LIKE', "%{$get[$key]}%");
259
+                } else if ($key == 'typeid') {
260
+                    $typeids = model('Arctype')->getHasChildren($get[$key]);
261
+                    $condition['a.typeid'] = array('IN', array_keys($typeids));
262
+                } else {
263
+                    $condition['a.'.$key] = array('eq', $get[$key]);
264
+                }
265
+            }
266
+        }
267
+
268
+        $condition['a.form_type'] = 0;
269
+        $condition['b.id'] = ['gt', 0];
270
+        $condition['a.is_del'] = 0;
271
+        $condition['a.lang'] = $this->admin_lang;
272
+
273
+        $count = Db::name('guestbook_attribute')->alias('a')
274
+            ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
275
+            ->where($condition)
276
+            ->count();
277
+        $Page = new Page($count, config('paginate.list_rows'));
278
+        $list = Db::name('guestbook_attribute')
279
+            ->field("a.attr_id")
280
+            ->alias('a')
281
+            ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
282
+            ->where($condition)
283
+            ->order('a.typeid desc, a.sort_order asc, a.attr_id asc')
284
+            ->limit($Page->firstRow.','.$Page->listRows)
285
+            ->getAllWithIndex('attr_id');
286
+
287
+        if ($list) {
288
+            $attr_ida = array_keys($list);
289
+            $fields = "b.*, a.*,a.attr_id as orgin_attr_id";
290
+            $row = Db::name('guestbook_attribute')
291
+                ->field($fields)
292
+                ->alias('a')
293
+                ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
294
+                ->where('a.attr_id', 'in', $attr_ida)
295
+                ->getAllWithIndex('attr_id');
296
+            $row = model('LanguageAttr')->getBindValue($row, 'guestbook_attribute', $this->main_lang); // 获取多语言关联绑定的值
297
+            foreach ($row as $key => $val) {
298
+                $val['fieldname'] = 'attr_'.$val['attr_id'];
299
+                $row[$key] = $val;
300
+            }
301
+            foreach ($list as $key => $val) {
302
+                $list[$key] = $row[$val['attr_id']];
303
+            }
304
+        }
305
+        $show = $Page->show();
306
+        $assign_data['page'] = $show;
307
+        $assign_data['list'] = $list;
308
+        $assign_data['pager'] = $Page;
309
+
310
+        //获取当前模型栏目
311
+        $select_html = allow_release_arctype($typeid, array($this->channeltype));
312
+        $typeidNum = substr_count($select_html, '</option>');
313
+        $this->assign('select_html',$select_html);
314
+        $this->assign('typeidNum',$typeidNum);
315
+        $assign_data['typeid'] = $typeid;
316
+        //当前栏目信息
317
+        $arctype_info = array();
318
+        if ($typeid > 0) {
319
+            $arctype_info = Db::name('arctype')->field('typename')->find($typeid);
320
+        }
321
+        $assign_data['arctype_info'] = $arctype_info;
322
+        $tab                = input('param.tab/d', 3);//选项卡
323
+        $assign_data['tab'] = $tab;
324
+        $assign_data['attrInputTypeArr'] = $this->attrInputTypeArr; // 表单类型
325
+        $this->assign($assign_data);
326
+        return $this->fetch();
327
+    }
328
+
329
+    /**
330
+     * 新增留言表单
331
+     */
332
+    public function attribute_add()
333
+    {
334
+        //防止php超时
335
+        function_exists('set_time_limit') && set_time_limit(0);
336
+        
337
+        if (is_language() && empty($this->globalConfig['language_split'])) {
338
+            $this->language_access(); // 多语言功能操作权限
339
+        }
340
+
341
+        if(IS_AJAX && IS_POST)//ajax提交验证
342
+        {
343
+            $model = model('GuestbookAttribute');
344
+
345
+            $attr_values = str_replace('_', '', input('attr_values')); // 替换特殊字符
346
+            $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
347
+            $attr_values = trim($attr_values);
348
+
349
+            /*过滤重复值*/
350
+            $attr_values_arr = explode(PHP_EOL, $attr_values);
351
+            foreach ($attr_values_arr as $key => $val) {
352
+                $tmp_val = trim($val);
353
+                if (empty($tmp_val)) {
354
+                    unset($attr_values_arr[$key]);
355
+                    continue;
356
+                }
357
+                $attr_values_arr[$key] = $tmp_val;
358
+            }
359
+            $attr_values_arr = array_unique($attr_values_arr);
360
+            $attr_values = implode(PHP_EOL, $attr_values_arr);
361
+            /*end*/
362
+            
363
+            $post_data = input('post.');
364
+            $post_data['attr_values'] = $attr_values;
365
+            $attr_input_type = isset($post_data['attr_input_type']) ? $post_data['attr_input_type'] : 0;
366
+
367
+            /*前台输入是否JS验证*/
368
+            $validate_type = 0;
369
+            $validate_type_list = config("global.validate_type_list"); // 前台输入验证类型
370
+            if (!empty($validate_type_list[$attr_input_type])) {
371
+                $validate_type = $attr_input_type;
372
+            }
373
+            /*end*/
374
+            if (9 == $post_data['attr_input_type']) {
375
+                if (!empty($post_data['region_data'])) {
376
+                    $post_data['attr_values']     = serialize($post_data['region_data']);
377
+                } else {
378
+                    $this->error("请选择区域范围!");
379
+                }
380
+            }
381
+            $savedata = array(
382
+                'attr_name'       => $post_data['attr_name'],
383
+                'typeid'          => $post_data['typeid'],
384
+                'form_type'       => 0,
385
+                'attr_input_type' => $attr_input_type,
386
+                'attr_values'     => isset($post_data['attr_values']) ? $post_data['attr_values'] : '',
387
+                'is_showlist'     => $post_data['is_showlist'],
388
+                'required'        => $post_data['required'],
389
+                'real_validate'   => $post_data['real_validate'],
390
+                'validate_type'   => $validate_type,
391
+                'sort_order'      => 100,
392
+                'lang'            => $this->admin_lang,
393
+                'add_time'        => getTime(),
394
+                'update_time'     => getTime(),
395
+            );
396
+
397
+            // 如果是添加手机号码类型则执行
398
+            if (!empty($savedata['typeid']) && 6 === intval($savedata['attr_input_type']) && 1 === intval($savedata['real_validate'])) {
399
+                // 查询是否已添加需要真实验证的手机号码类型
400
+                $where = [
401
+                    'typeid' => $savedata['typeid'],
402
+                    'form_type'       => 0,
403
+                    'real_validate' => $savedata['real_validate'],
404
+                    'attr_input_type' => $savedata['attr_input_type']
405
+                ];
406
+                $realValidate = $model->get($where);
407
+                if (!empty($realValidate)) $this->error('只能设置一个需要真实验证的手机号码类型');
408
+            }
409
+
410
+            // 数据验证
411
+            $validate = \think\Loader::validate('GuestbookAttribute');
412
+            if(!$validate->batch()->check($savedata))
413
+            {
414
+                $error = $validate->getError();
415
+                $error_msg = array_values($error);
416
+                $return_arr = array(
417
+                    'status' => -1,
418
+                    'msg' => $error_msg[0],
419
+                    'data' => $error,
420
+                );
421
+                respose($return_arr);
422
+            } else {
423
+                $model->data($savedata,true); // 收集数据
424
+                $model->save(); // 写入数据到数据库
425
+                $insertId = $model->getLastInsID();
426
+
427
+                /*同步留言属性ID到多语言的模板变量里*/
428
+                model('GuestbookAttribute')->syn_add_language_attribute($insertId);
429
+                /*--end*/
430
+
431
+                $return_arr = array(
432
+                     'status' => 1,
433
+                     'msg'   => '操作成功',                        
434
+                     'data'  => array('url'=>url('Guestbook/attribute_index', array('typeid'=>$post_data['typeid']))),
435
+                );
436
+                adminLog('新增留言表单:'.$savedata['attr_name']);
437
+                respose($return_arr);
438
+            }
439
+        }
440
+
441
+        $typeid = input('param.typeid/d', 0);
442
+        if ($typeid > 0) {
443
+            $select_html = Db::name('arctype')->where('id', $typeid)->getField('typename');
444
+            $select_html = !empty($select_html) ? $select_html : '该栏目不存在';
445
+        } else {
446
+            $arctypeLogic      = new ArctypeLogic();
447
+            $map               = array(
448
+                'channeltype' => $this->channeltype,
449
+            );
450
+            $arctype_max_level = intval(config('global.arctype_max_level'));
451
+            $select_html       = $arctypeLogic->arctype_list(0, $typeid, true, $arctype_max_level, $map);
452
+        }
453
+        $assign_data['select_html'] = $select_html; //
454
+        $assign_data['typeid']      = $typeid; // 栏目ID
455
+
456
+        $assign_data['attrInputTypeArr'] = $this->attrInputTypeArr; // 表单类型
457
+        //区域
458
+        $China[]                 = [
459
+            'id'   => 0,
460
+            'name' => '全国',
461
+        ];
462
+        $Province                = get_province_list();
463
+        $assign_data['Province'] = array_merge($China, $Province);
464
+        $this->assign($assign_data);
465
+        return $this->fetch();
466
+    }
467
+
468
+    /**
469
+     * 编辑留言表单
470
+     */
471
+    public function attribute_edit()
472
+    {
473
+        if(IS_AJAX && IS_POST)//ajax提交验证
474
+        {
475
+            $model = model('GuestbookAttribute');
476
+
477
+            $attr_values = str_replace('_', '', input('attr_values')); // 替换特殊字符
478
+            $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
479
+            $attr_values = trim($attr_values);
480
+
481
+            /*过滤重复值*/
482
+            $attr_values_arr = explode(PHP_EOL, $attr_values);
483
+            foreach ($attr_values_arr as $key => $val) {
484
+                $tmp_val = trim($val);
485
+                if (empty($tmp_val)) {
486
+                    unset($attr_values_arr[$key]);
487
+                    continue;
488
+                }
489
+                $attr_values_arr[$key] = $tmp_val;
490
+            }
491
+            $attr_values_arr = array_unique($attr_values_arr);
492
+            $attr_values = implode(PHP_EOL, $attr_values_arr);
493
+            /*end*/
494
+            
495
+            $post_data = input('post.');
496
+            $post_data['attr_id'] = intval($post_data['attr_id']);
497
+            $post_data['attr_values'] = $attr_values;
498
+            $attr_input_type = isset($post_data['attr_input_type']) ? $post_data['attr_input_type'] : 0;
499
+
500
+            /*前台输入是否JS验证*/
501
+            $validate_type = 0;
502
+            $validate_type_list = config("global.validate_type_list"); // 前台输入验证类型
503
+            if (!empty($validate_type_list[$attr_input_type])) {
504
+                $validate_type = $attr_input_type;
505
+            }
506
+            /*end*/
507
+            if (9 == $post_data['attr_input_type']) {
508
+                if (!empty($post_data['region_data'])) {
509
+                    $post_data['attr_values']     = serialize($post_data['region_data']);
510
+                } else {
511
+                    $this->error("请选择区域范围!");
512
+                }
513
+            }
514
+            $savedata = array(
515
+                'attr_id'         => $post_data['attr_id'],
516
+                'attr_name'       => $post_data['attr_name'],
517
+                'typeid'          => $post_data['typeid'],
518
+                'form_type'       => 0,
519
+                'attr_input_type' => $attr_input_type,
520
+                'attr_values'     => isset($post_data['attr_values']) ? $post_data['attr_values'] : '',
521
+                'is_showlist'     => $post_data['is_showlist'],
522
+                'required'        => $post_data['required'],
523
+                'real_validate'   => $post_data['real_validate'],
524
+                'validate_type'   => $validate_type,
525
+                'sort_order'      => 100,
526
+                'update_time'     => getTime(),
527
+            );
528
+
529
+            // 如果是添加手机号码类型则执行
530
+            if (!empty($savedata['typeid']) && 6 === intval($savedata['attr_input_type']) && 1 === intval($savedata['real_validate'])) {
531
+                // 查询是否已添加需要真实验证的手机号码类型
532
+                $where = [
533
+                    'typeid' => $savedata['typeid'],
534
+                    'form_type'       => 0,
535
+                    'attr_id' => ['NEQ', $savedata['attr_id']],
536
+                    'real_validate' => $savedata['real_validate'],
537
+                    'attr_input_type' => $savedata['attr_input_type']
538
+                ];
539
+                $realValidate = $model->get($where);
540
+                if (!empty($realValidate)) $this->error('只能设置一个需要真实验证的手机号码类型');
541
+            }
542
+            
543
+            // 数据验证            
544
+            $validate = \think\Loader::validate('GuestbookAttribute');
545
+            if(!$validate->batch()->check($savedata))
546
+            {
547
+                $error      = $validate->getError();
548
+                $error_msg  = array_values($error);
549
+                $return_arr = array(
550
+                    'status' => -1,
551
+                    'msg'    => $error_msg[0],
552
+                    'data'   => $error,
553
+                );
554
+                respose($return_arr);
555
+            } else {
556
+                $model->data($savedata, true); // 收集数据
557
+                $model->isUpdate(true, [
558
+                    'attr_id' => $post_data['attr_id'],
559
+                ])->save(); // 写入数据到数据库
560
+                $return_arr = array(
561
+                    'status' => 1,
562
+                    'msg'    => '操作成功',
563
+                    'data'   => array('url' => url('Guestbook/attribute_index', array('typeid' => intval($post_data['typeid'])))),
564
+                );
565
+                adminLog('编辑留言表单:' . $savedata['attr_name']);
566
+                respose($return_arr);
567
+            }
568
+        }
569
+
570
+        $assign_data = array();
571
+
572
+        $id = input('id/d');
573
+        /*获取多语言关联绑定的值*/
574
+        $new_id = model('LanguageAttr')->getBindValue($id, 'guestbook_attribute'); // 多语言
575
+        !empty($new_id) && $id = $new_id;
576
+        /*--end*/
577
+        $info = Db::name('GuestbookAttribute')->where([
578
+            'attr_id' => $id,
579
+            'form_type' => 0,
580
+        ])->find();
581
+        if (empty($info)) {
582
+            $this->error('数据不存在,请联系管理员!');
583
+            exit;
584
+        }
585
+        $assign_data['field'] = $info;
586
+
587
+        // 所在栏目
588
+        $select_html                = Db::name('arctype')->where('id', $info['typeid'])->getField('typename');
589
+        $select_html                = !empty($select_html) ? $select_html : '该栏目不存在';
590
+        $assign_data['select_html'] = $select_html;
591
+
592
+        $assign_data['attrInputTypeArr'] = $this->attrInputTypeArr; // 表单类型
593
+        /*区域字段处理*/
594
+        // 初始化参数
595
+        $assign_data['region'] = [
596
+            'parent_id'    => '-1',
597
+            'region_id'    => '-1',
598
+            'region_names' => '',
599
+            'region_ids'   => '',
600
+        ];
601
+        // 定义全国参数
602
+        $China[] = [
603
+            'id'   => 0,
604
+            'name' => '全国',
605
+        ];
606
+        // 查询省份信息并且拼装上$China数组
607
+        $Province                = get_province_list();
608
+        $assign_data['Province'] = array_merge($China, $Province);
609
+        // 区域选择时,指定不出现下级地区列表
610
+        $assign_data['parent_array'] = "[]";
611
+        // 如果是区域类型则执行
612
+        if (9 == $info['attr_input_type']) {
613
+            // 反序列化默认值参数
614
+            $dfvalue = unserialize($info['attr_values']);
615
+            if (0 == $dfvalue['region_id']) {
616
+                $parent_id = $dfvalue['region_id'];
617
+            } else {
618
+                // 查询当前选中的区域父级ID
619
+                $parent_id = Db::name('region')->where("id", $dfvalue['region_id'])->getField('parent_id');
620
+                if (0 == $parent_id) {
621
+                    $parent_id = $dfvalue['region_id'];
622
+                }
623
+            }
624
+
625
+            // 查询市\区\县信息
626
+            $assign_data['City'] = Db::name('region')->where("parent_id", $parent_id)->select();
627
+            // 加载数据到模板
628
+            $assign_data['region'] = [
629
+                'parent_id'    => $parent_id,
630
+                'region_id'    => $dfvalue['region_id'],
631
+                'region_names' => $dfvalue['region_names'],
632
+                'region_ids'   => $dfvalue['region_ids'],
633
+            ];
634
+
635
+            // 删除默认值,防止切换其他类型时使用到
636
+            unset($info['attr_values']);
637
+
638
+            // 区域选择时,指定不出现下级地区列表
639
+            $assign_data['parent_array'] = convert_js_array(config('global.field_region_all_type'));
640
+        }
641
+        /*区域字段处理结束*/
642
+        $this->assign($assign_data);
643
+        return $this->fetch();
644
+    }
645
+    
646
+    /**
647
+     * 删除留言表单
648
+     */
649
+    public function attribute_del()
650
+    {
651
+        if (is_language() && empty($this->globalConfig['language_split'])) {
652
+            $this->language_access(); // 多语言功能操作权限
653
+        }
654
+
655
+        $thorough = input('thorough/d');
656
+        $id_arr = input('del_id/a');
657
+        $id_arr = eyIntval($id_arr);
658
+        if (!empty($id_arr)) {
659
+            //多语言
660
+            $attr_name_arr = [];
661
+            foreach ($id_arr as $key => $val) {
662
+                $attr_name_arr[] = 'attr_' . $val;
663
+            }
664
+            if (is_language() && empty($this->globalConfig['language_split'])) {
665
+                $new_id_arr = Db::name('language_attr')->where([
666
+                        'attr_name'  => ['IN', $attr_name_arr],
667
+                        'attr_group' => 'guestbook_attribute',
668
+                    ])->column('attr_value');
669
+                !empty($new_id_arr) && $id_arr = $new_id_arr;
670
+            }
671
+            if (1 == $thorough){//彻底删除
672
+                $r = Db::name('GuestbookAttribute')->where([
673
+                    'attr_id' => ['IN', $id_arr],
674
+                    'form_type' => 0,
675
+                ])->delete();
676
+            }else{
677
+                $r = Db::name('GuestbookAttribute')->where([
678
+                    'attr_id' => ['IN', $id_arr],
679
+                    'form_type' => 0,
680
+                ])->update([
681
+                    'is_del'      => 1,
682
+                    'update_time'   => getTime(),
683
+                ]);
684
+            }
685
+            if($r !== false){
686
+                // 删除多语言留言属性关联绑定
687
+                if (1 == $thorough){//彻底删除
688
+                    if (!empty($attr_name_arr)) {
689
+                        if (get_admin_lang() == get_main_lang()) {
690
+                            Db::name('language_attribute')->where([
691
+                                    'attr_name' => ['IN', $attr_name_arr],
692
+                                    'attr_group'    => 'guestbook_attribute',
693
+                                ])->delete();
694
+                        }
695
+                        if (empty($this->globalConfig['language_split'])) {
696
+                            Db::name('language_attr')->where([
697
+                                    'attr_name' => ['IN', $attr_name_arr],
698
+                                    'attr_group'    => 'guestbook_attribute',
699
+                                ])->delete();
700
+                        } else {
701
+                            Db::name('language_attr')->where([
702
+                                    'attr_value' => ['IN', $id_arr],
703
+                                    'attr_group'    => 'guestbook_attribute',
704
+                                ])->delete();
705
+                        }
706
+                    }
707
+                }
708
+                /*--end*/
709
+                adminLog('删除留言表单-id:'.implode(',', $id_arr));
710
+                $this->success('删除成功');
711
+            }
712
+        }
713
+        $this->error('删除失败');
714
+    }
715
+
716
+    /**
717
+     * 查看详情
718
+     */
719
+    public function details()
720
+    {
721
+        $aid = input('param.aid/d');
722
+        $form_type = input('param.form_type/d', 0);
723
+
724
+        // 标记为已读和IP地区
725
+        if (1 == $form_type) {
726
+            $row = Db::name('guestbook')->field('a.*, b.form_name')
727
+                ->alias('a')
728
+                ->join('form b','a.typeid = b.form_id','left')
729
+                ->where(['a.aid'=>$aid, 'a.form_type'=>$form_type])
730
+                ->find();
731
+        } else {
732
+            $row = Db::name('guestbook')->field('a.*, b.typename as form_name')
733
+                ->alias('a')
734
+                ->join('arctype b','a.typeid = b.id','left')
735
+                ->where(['a.aid'=>$aid, 'a.form_type'=>$form_type])
736
+                ->find();
737
+        }
738
+        $city = "";
739
+        $city_arr = getCityLocation($row['ip']);
740
+        if (!empty($city_arr)) {
741
+            !empty($city_arr['location']) && $city .= $city_arr['location'];
742
+        }
743
+        $row['city'] = $city;
744
+        // 标记为已读
745
+        if (empty($row['is_read'])) {
746
+            $row['is_read'] = 1;
747
+            $row['update_time'] = getTime();
748
+            Db::name('guestbook')->where(['aid'=>$aid])->update([
749
+                    'is_read'   => $row['is_read'],
750
+                    'update_time'   => $row['update_time'],
751
+                ]);
752
+        }
753
+        $this->assign('row', $row);
754
+
755
+        // 留言属性
756
+        $attr_list = Db::name('guestbook_attribute')->where(['typeid'=>$row['typeid'],'form_type'=>$form_type])->order('attr_id asc')->select();
757
+        $attr_values = Db::name('guestbook_attr')->field('attr_id,attr_value')->where(['aid'=>$aid,'form_type'=>$form_type])->getAllWithIndex('attr_id');
758
+        foreach ($attr_list as $key => $val) {
759
+            $val['attr_value'] = empty($attr_values[$val['attr_id']]) ? '' : $attr_values[$val['attr_id']]['attr_value'];
760
+            $attr_list[$key] = $val;
761
+        }
762
+        foreach ($attr_list as $key => &$val) {
763
+            if ($val['attr_input_type'] == 9) {
764
+                $val['attr_value'] = Db::name('region')->where('id','in',$val['attr_value'])->column('name');
765
+                $val['attr_value'] = implode('',$val['attr_value']);
766
+            } else if ($val['attr_input_type'] == 4) {
767
+                $val['attr_value'] = filter_line_return($val['attr_value'], '、');
768
+            } else if(10 == $val['attr_input_type']){
769
+                $val['attr_value'] = date('Y-m-d H:i:s',$val['attr_value']);
770
+            } else if(11 == $val['attr_input_type']) {
771
+                $attrValueArr = !empty($val['attr_value']) ? explode(',', $val['attr_value']) : [];
772
+                $val['attr_value'] = '';
773
+                foreach ($attrValueArr as $value) {
774
+                    if (preg_match('/(\.('.tpCache('global.image_type').'))$/i', $value)) {
775
+                        if (!stristr($value, '|')) {
776
+                            $value = handle_subdir_pic($value);
777
+                            $val['attr_value'] .= "<a class='guest-pic' href='{$value}' target='_blank'><img src='{$value}' width='60' height='60' style='float: unset; cursor: pointer;'/></a>";
778
+                        }
779
+                    } elseif (preg_match('/(\.('.tpCache('global.file_type').'))$/i', $value)) {
780
+                        if (!stristr($value, '|')) {
781
+                            $value = handle_subdir_pic($value);
782
+                            $val['attr_value'] .= "<a href='{$value}' download='".time()."'><img src=\"".ROOT_DIR."/public/static/common/images/file.png\" alt=\"\" style=\"width: 16px; height: 16px;\">文件下载</a>";
783
+                        }
784
+                    }
785
+                }
786
+            } else {
787
+                if (preg_match('/(\.(jpg|gif|png|bmp|jpeg|ico|webp))$/i', $val['attr_value'])) {
788
+                    if (!stristr($val['attr_value'], '|')) {
789
+                        $val['attr_value'] = handle_subdir_pic($val['attr_value']);
790
+                        $val['attr_value'] = "<a href='{$val['attr_value']}' target='_blank'><img src='{$val['attr_value']}' width='60' height='60' style='float: unset;cursor: pointer;' /></a>";
791
+                    }
792
+                }elseif (preg_match('/(\.('.tpCache('global.file_type').'))$/i', $val['attr_value'])){
793
+                    if (!stristr($val['attr_value'], '|')) {
794
+                        $val['attr_value'] = handle_subdir_pic($val['attr_value']);
795
+                        $val['attr_value'] = "<a href='{$val['attr_value']}' download='".time()."'><img src=\"".ROOT_DIR."/public/static/common/images/file.png\" alt=\"\" style=\"width: 16px;height:  16px;\">点击下载</a>";
796
+                    }
797
+                }
798
+            }
799
+        }
800
+
801
+        $this->assign('attr_list', $attr_list);
802
+
803
+        // 如果安装手机端后台管理插件并且在手机端访问时执行
804
+        $isMobile = input('param.isMobile/d', 0);
805
+        if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
806
+            return $this->display('form/details');
807
+        } else {
808
+            return $this->fetch();
809
+        }
810
+    }
811
+
812
+    /**    
813
+     * excel导出
814
+     */
815
+    public function ajax_excel_export()
816
+    {
817
+        $id_arr          = input('aid/s');
818
+        if (!empty($id_arr)) {
819
+            $id_arr          = explode(',', $id_arr);
820
+            $id_arr          = eyIntval($id_arr);
821
+        }
822
+        $typeid          = input('typeid/d');
823
+        $start_time      = input('start_time/s');
824
+        $end_time        = input('end_time/s');
825
+        $form_type = input('param.form_type/s', 0);
826
+
827
+        $strTable        = '<table width="500" border="1">';
828
+        $where           = [];
829
+        if (!empty($typeid)) $where['typeid'] = $typeid;
830
+        if ('all' != $form_type) $where['form_type'] = intval($form_type);
831
+        $where['lang']   = $this->admin_lang;
832
+        $order           = 'add_time asc';
833
+        //没有指定ID就导出全部
834
+        if (!empty($id_arr)) {
835
+            $where['aid'] = ['IN', $id_arr];
836
+        }
837
+        //根据日期导出
838
+        if (!empty($start_time) && !empty($end_time)) {
839
+            $start_time        = strtotime($start_time);
840
+            $end_time          = strtotime("+1 day", strtotime($end_time)) - 1;
841
+            $where['add_time'] = ['between', [$start_time, $end_time]];
842
+        } elseif (!empty($start_time) && empty($end_time)) {
843
+            $start_time        = strtotime($start_time);
844
+            $where['add_time'] = ['>=', $start_time];
845
+        } elseif (empty($start_time) && !empty($end_time)) {
846
+            $end_time          = strtotime("+1 day", strtotime($end_time)) - 1;
847
+            $where['add_time'] = ['<=', $end_time];
848
+        }
849
+        $row = Db::name('guestbook')->where($where)->order($order)->select();
850
+
851
+        $map = [];
852
+        if (!empty($typeid)) $map['typeid'] = $typeid;
853
+        if ('all' != $form_type) $map['form_type'] = intval($form_type);
854
+        $map['lang']   = $this->admin_lang;
855
+        $map['is_del'] = 0;
856
+        $title = Db::name('guestbook_attribute')->where($map)->order('sort_order asc, attr_id asc')->select();
857
+
858
+        if ($row && $title) {
859
+            $strTable .= '<tr>';
860
+            $strTable .= '<td style="text-align:center;font-size:12px;" width="*">ID</td>';
861
+            foreach ($title as &$key) {
862
+                $strTable .= '<td style="text-align:center;font-size:12px;" width="*">' . $key['attr_name'] . '</td>';
863
+            }
864
+            $strTable .= '<td style="text-align:center;font-size:12px;" width="*">新增时间</td>';
865
+            $strTable .= '<td style="text-align:center;font-size:12px;" width="*">更新时间</td>';
866
+            $strTable .= '</tr>';
867
+
868
+            foreach ($row as &$val) {
869
+                $attr_value = Db::name('guestbook_attr')
870
+                    ->alias('a')
871
+                    ->field('a.*,b.attr_input_type')
872
+                    ->where(['a.aid' => $val['aid'], 'a.lang' => $this->admin_lang])
873
+                    ->join('guestbook_attribute b','a.attr_id = b.attr_id')
874
+                    ->getAllWithIndex('attr_id');
875
+                foreach ($attr_value as $k => $v){
876
+                    if ($v['attr_input_type'] == 9){
877
+                        $v['attr_value'] = Db::name('region')->where('id','in',$v['attr_value'])->column('name');
878
+                        $attr_value[$k]['attr_value'] = implode('',$v['attr_value']);
879
+                    }else if(10 == $v['attr_input_type']){
880
+                        $attr_value[$k]['attr_value'] =  date('Y-m-d H:i:s',$v['attr_value']);
881
+                    }else if(in_array($v['attr_input_type'],[5,8])){     //单张图、附件
882
+                        if (!stristr($val['attr_value'], '|')){
883
+                            $attr_value[$k]['attr_value'] = handle_subdir_pic($v['attr_value'],'img',true);
884
+                        }
885
+                    }else if(11 == $v['attr_input_type']){  //多张图
886
+                        $attr_value_arr = explode(",",$v['attr_value']);
887
+                        foreach ($attr_value_arr as $attr_value_k => $attr_value_v){
888
+                            $attr_value_arr[$attr_value_k] = handle_subdir_pic($attr_value_v,'img',true);
889
+                        }
890
+                        $attr_value[$k]['attr_value'] = implode(PHP_EOL,$attr_value_arr);
891
+                    }
892
+                }
893
+
894
+                $strTable   .= '<tr>';
895
+                $strTable   .= '<td style="text-align:center;font-size:12px;">' . $val['aid'] . '</td>';
896
+                foreach ($title as &$key) {
897
+                    $strTable .= '<td style="text-align:center;font-size:12px;" style=\'vnd.ms-excel.numberformat:@\' width="*">' . $attr_value[$key['attr_id']]['attr_value'] . '</td>';
898
+                }
899
+                $strTable .= '<td style="text-align:left;font-size:12px;">' . date('Y-m-d H:i:s', $val['add_time']) . '</td>';
900
+                $strTable .= '<td style="text-align:left;font-size:12px;">' . date('Y-m-d H:i:s', $val['update_time']) . '</td>';
901
+                $strTable .= '</tr>';
902
+            }
903
+        }
904
+        $strTable .= '</table>';
905
+        if ('all' === $form_type) {
906
+            downloadExcel($strTable, 'allwords');
907
+        } else if (1 == $form_type) {
908
+            downloadExcel($strTable, 'form');
909
+        } else {
910
+            downloadExcel($strTable, 'guestbook');
911
+        }
912
+        exit();
913
+    }
914
+
915
+    /**
916
+     * 设置/取消星标
917
+     * @return [type] [description]
918
+     */
919
+    public function ajax_set_star()
920
+    {
921
+        $aid = input('param.aid/d');
922
+        $is_star = input('param.is_star/d');
923
+        if (IS_AJAX && !empty($aid)) {
924
+            $r = Db::name('guestbook')->where(['aid'=>$aid])->update([
925
+                    'is_star' => $is_star,
926
+                ]);
927
+            if ($r !== false) {
928
+                if ($is_star == 1) {
929
+                    $this->success('星标成功');
930
+                } else {
931
+                    $this->success('取消成功');
932
+                }
933
+            }
934
+        }
935
+        $this->error('操作失败');
936
+    }
937
+}

+ 742
- 0
application/admin/controller/Images.php View File

@@ -0,0 +1,742 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+
19
+class Images extends Base
20
+{
21
+    // 模型标识
22
+    public $nid = 'images';
23
+    // 模型ID
24
+    public $channeltype = '';
25
+    
26
+    public function _initialize() {
27
+        parent::_initialize();
28
+        $channeltype_list = config('global.channeltype_list');
29
+        $this->channeltype = $channeltype_list[$this->nid];
30
+        empty($this->channeltype) && $this->channeltype = 3;
31
+        $this->assign('nid', $this->nid);
32
+        $this->assign('channeltype', $this->channeltype);
33
+
34
+        // 返回页面
35
+        $paramTypeid = input('param.typeid/d', 0);
36
+        $this->callback_url = url('Images/index', ['lang' => $this->admin_lang, 'typeid' => $paramTypeid]);
37
+        $this->assign('callback_url', $this->callback_url);
38
+    }
39
+
40
+    //列表
41
+    public function index()
42
+    {
43
+        $assign_data = $condition = [];
44
+
45
+        // 获取到所有GET参数
46
+        $param = input('param.');
47
+        $typeid = input('typeid/d', 0);
48
+
49
+        // 搜索、筛选查询条件处理
50
+        foreach (['keywords', 'typeid', 'flag', 'is_release','province_id','city_id','area_id'] as $key) {
51
+            if ($key == 'typeid' && empty($param['typeid'])) {
52
+                $typeids = Db::name('arctype')->where('current_channel', $this->channeltype)->column('id');
53
+                $condition['a.typeid'] = array('IN', $typeids);
54
+            }
55
+            if (isset($param[$key]) && $param[$key] !== '') {
56
+                if ($key == 'keywords') {
57
+                    $keywords = $param[$key];
58
+                    $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
59
+                } else if ($key == 'typeid') {
60
+                    $typeid = $param[$key];
61
+                    $hasRow = model('Arctype')->getHasChildren($typeid);
62
+                    $typeids = get_arr_column($hasRow, 'id');
63
+                    // 权限控制 by 小虎哥
64
+                    $admin_info = session('admin_info');
65
+                    if (0 < intval($admin_info['role_id'])) {
66
+                        $auth_role_info = $admin_info['auth_role_info'];
67
+                        if (!empty($typeid) && !empty($auth_role_info) && !empty($auth_role_info['permission']['arctype'])) {
68
+                            $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
69
+                        }
70
+                    }
71
+                    $condition['a.typeid'] = array('IN', $typeids);
72
+                } else if ($key == 'flag') {
73
+                    if ('is_release' == $param[$key]) {
74
+                        $condition['a.users_id'] = array('gt', 0);
75
+                    } else {
76
+                        $FlagNew = $param[$key];
77
+                        $condition['a.'.$param[$key]] = array('eq', 1);
78
+                    }
79
+                } else if (in_array($key, ['province_id','city_id','area_id'])) {
80
+                    if (!empty($param['area_id'])) {
81
+                        $condition['a.area_id'] = $param['area_id'];
82
+                    } else if (!empty($param['city_id'])) {
83
+                        $condition['a.city_id'] = $param['city_id'];
84
+                    } else if (!empty($param['province_id'])) {
85
+                        $condition['a.province_id'] = $param['province_id'];
86
+                    }
87
+                } else {
88
+                    $condition['a.'.$key] = array('eq', $param[$key]);
89
+                }
90
+            }
91
+        }
92
+
93
+        // 权限控制 by 小虎哥
94
+        $admin_info = session('admin_info');
95
+        if (0 < intval($admin_info['role_id'])) {
96
+            $auth_role_info = $admin_info['auth_role_info'];
97
+            if (!empty($auth_role_info) && isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
98
+                $condition['a.admin_id'] = $admin_info['admin_id'];
99
+            }
100
+        }
101
+
102
+        // 时间检索条件
103
+        $begin = strtotime(input('add_time_begin'));
104
+        $end = strtotime(input('add_time_end'));
105
+        if ($begin > 0 && $end > 0) {
106
+            $condition['a.add_time'] = array('between', "$begin, $end");
107
+        } else if ($begin > 0) {
108
+            $condition['a.add_time'] = array('egt', $begin);
109
+        } else if ($end > 0) {
110
+            $condition['a.add_time'] = array('elt', $end);
111
+        }
112
+
113
+        // 必要条件
114
+        $condition['a.channel'] = array('eq', $this->channeltype);
115
+        $condition['a.lang'] = array('eq', $this->admin_lang);
116
+        $condition['a.is_del'] = array('eq', 0);
117
+        $conditionNew = "(a.users_id = 0 OR (a.users_id > 0 AND a.arcrank >= 0))";
118
+
119
+        // 自定义排序
120
+        $orderby = input('param.orderby/s');
121
+        $orderway = input('param.orderway/s');
122
+        if (!empty($orderby) && !empty($orderway)) {
123
+            $orderby = "a.{$orderby} {$orderway}, a.aid desc";
124
+        } else {
125
+            $orderby = "a.aid desc";
126
+        }
127
+
128
+        // 数据查询,搜索出主键ID的值
129
+        $SqlQuery = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->fetchSql()->count('aid');
130
+        $count = Db::name('sql_cache_table')->where(['sql_md5'=>md5($SqlQuery)])->getField('sql_result');
131
+        $count = ($count < 0) ? 0 : $count;
132
+        if (empty($count)) {
133
+            $count = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->count('aid');
134
+            /*添加查询执行语句到mysql缓存表*/
135
+            $SqlCacheTable = [
136
+                'sql_name' => '|images|' . $this->channeltype . '|',
137
+                'sql_result' => $count,
138
+                'sql_md5' => md5($SqlQuery),
139
+                'sql_query' => $SqlQuery,
140
+                'add_time' => getTime(),
141
+                'update_time' => getTime(),
142
+            ];
143
+            if (!empty($FlagNew)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $FlagNew . '|';
144
+            if (!empty($typeid)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $typeid . '|';
145
+            if (!empty($keywords)) $SqlCacheTable['sql_name'] = '|images|keywords|';
146
+            Db::name('sql_cache_table')->insertGetId($SqlCacheTable);
147
+            /*END*/
148
+        }
149
+
150
+        $Page = new Page($count, config('paginate.list_rows'));
151
+        $list = [];
152
+        if (!empty($count)) {
153
+            $limit = $count > config('paginate.list_rows') ? $Page->firstRow.','.$Page->listRows : $count;
154
+            $list = Db::name('archives')
155
+                ->field("a.aid")
156
+                ->alias('a')
157
+                ->where($condition)
158
+            	->where($conditionNew)
159
+                ->order($orderby)
160
+                ->limit($limit)
161
+                ->getAllWithIndex('aid');
162
+            if (!empty($list)) {
163
+                $aids = array_keys($list);
164
+                $fields = "b.*, a.*, a.aid as aid";
165
+                $row = Db::name('archives')
166
+                    ->field($fields)
167
+                    ->alias('a')
168
+                    ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
169
+                    ->where('a.aid', 'in', $aids)
170
+                    ->getAllWithIndex('aid');
171
+                foreach ($list as $key => $val) {
172
+                    $row[$val['aid']]['arcurl'] = get_arcurl($row[$val['aid']]);
173
+                    $row[$val['aid']]['litpic'] = handle_subdir_pic($row[$val['aid']]['litpic']);
174
+                    $list[$key] = $row[$val['aid']];
175
+                }
176
+            }
177
+        }
178
+
179
+        $show = $Page->show();
180
+        $assign_data['page'] = $show;
181
+        $assign_data['list'] = $list;
182
+        $assign_data['pager'] = $Page;
183
+        $assign_data['typeid'] = $typeid;
184
+        $assign_data['tab'] = input('param.tab/d', 3);// 选项卡
185
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();// 文档属性
186
+        $assign_data['arctype_info'] = $typeid > 0 ? Db::name('arctype')->field('typename')->find($typeid) : [];// 当前栏目信息
187
+        $this->assign($assign_data);
188
+        return $this->fetch();
189
+    }
190
+
191
+    /**
192
+     * 添加
193
+     */
194
+    public function add()
195
+    {
196
+        $admin_info = session('admin_info');
197
+        $auth_role_info = $admin_info['auth_role_info'];
198
+        $this->assign('auth_role_info', $auth_role_info);
199
+        $this->assign('admin_info', $admin_info);
200
+
201
+        if (IS_POST) {
202
+            $post = input('post.');
203
+            model('Archives')->editor_auto_210607($post);
204
+            /* 处理TAG标签 */
205
+            if (!empty($post['tags_new'])) {
206
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
207
+                unset($post['tags_new']);
208
+            }
209
+            $post['tags'] = explode(',', $post['tags']);
210
+            $post['tags'] = array_unique($post['tags']);
211
+            $post['tags'] = implode(',', $post['tags']);
212
+            /* END */
213
+
214
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
215
+
216
+            // 根据标题自动提取相关的关键字
217
+            $seo_keywords = $post['seo_keywords'];
218
+            if (!empty($seo_keywords)) {
219
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
220
+            } else {
221
+                // $seo_keywords = get_split_word($post['title'], $content);
222
+            }
223
+
224
+            // 自动获取内容第一张图片作为封面图
225
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
226
+            $litpic = '';
227
+            if ($is_remote == 1) {
228
+                $litpic = $post['litpic_remote'];
229
+            } else {
230
+                $litpic = $post['litpic_local'];
231
+            }
232
+            if (empty($litpic)) {
233
+                $litpic = get_html_first_imgurl($content);
234
+            }
235
+            $post['litpic'] = $litpic;
236
+
237
+            /*是否有封面图*/
238
+            if (empty($post['litpic'])) {
239
+                $is_litpic = 0; // 无封面图
240
+            } else {
241
+                $is_litpic = 1; // 有封面图
242
+            }
243
+
244
+            // SEO描述
245
+            $seo_description = '';
246
+            if (empty($post['seo_description']) && !empty($content)) {
247
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
248
+            } else {
249
+                $seo_description = $post['seo_description'];
250
+            }
251
+
252
+            // 外部链接跳转
253
+            $jumplinks = '';
254
+            $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
255
+            if (intval($is_jump) > 0) {
256
+                $jumplinks = $post['jumplinks'];
257
+            }
258
+
259
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
260
+            if ($post['type_tempview'] == $post['tempview']) {
261
+                unset($post['type_tempview']);
262
+                unset($post['tempview']);
263
+            }
264
+
265
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
266
+            $htmlfilename = trim($post['htmlfilename']);
267
+            if (!empty($htmlfilename)) {
268
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
269
+                // $htmlfilename = strtolower($htmlfilename);
270
+                //判断是否存在相同的自定义文件名
271
+                $map = [
272
+                    'htmlfilename'  => $htmlfilename,
273
+                    'lang'  => $this->admin_lang,
274
+                ];
275
+                if (!empty($post['typeid'])) {
276
+                    $map['typeid'] = array('eq', $post['typeid']);
277
+                }
278
+                $filenameCount = Db::name('archives')->where($map)->count();
279
+                if (!empty($filenameCount)) {
280
+                    $this->error("同栏目下,自定义文件名已存在!");
281
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
282
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
283
+                }
284
+            } else {
285
+                // 处理外贸链接
286
+                if (is_dir('./weapp/Waimao/')) {
287
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
288
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'add', $this->globalConfig);
289
+                }
290
+            }
291
+            $post['htmlfilename'] = $htmlfilename;
292
+
293
+            //做自动通过审核判断
294
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
295
+                $post['arcrank'] = -1;
296
+            }
297
+
298
+            // 副栏目
299
+            if (isset($post['stypeid'])) {
300
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
301
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
302
+                $post['stypeid'] = trim($post['stypeid'], ',');
303
+                $post['stypeid'] = str_replace(",{$post['typeid']},", ',', ",{$post['stypeid']},");
304
+                $post['stypeid'] = trim($post['stypeid'], ',');
305
+            }
306
+
307
+            // --存储数据
308
+            $newData = array(
309
+                'typeid'=> empty($post['typeid']) ? 0 : $post['typeid'],
310
+                'channel'   => $this->channeltype,
311
+                'is_b'      => empty($post['is_b']) ? 0 : $post['is_b'],
312
+                'is_head'      => empty($post['is_head']) ? 0 : $post['is_head'],
313
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
314
+                'is_recom'      => empty($post['is_recom']) ? 0 : $post['is_recom'],
315
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
316
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
317
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
318
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
319
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
320
+                'is_jump'     => $is_jump,
321
+                'is_litpic'     => $is_litpic,
322
+                'jumplinks' => $jumplinks,
323
+                'origin'      => empty($post['origin']) ? '网络' : $post['origin'],
324
+                'seo_keywords'     => $seo_keywords,
325
+                'seo_description'     => $seo_description,
326
+                'admin_id'  => session('admin_info.admin_id'),
327
+                'lang'  => $this->admin_lang,
328
+                'sort_order'    => 100,
329
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
330
+                'add_time'     => strtotime($post['add_time']),
331
+                'update_time'  => strtotime($post['add_time']),
332
+            );
333
+            $data = array_merge($post, $newData);
334
+
335
+            $aid = Db::name('archives')->insertGetId($data);
336
+            $_POST['aid'] = $aid;
337
+            if ($aid) {
338
+                // ---------后置操作
339
+                model('Images')->afterSave($aid, $data, 'add');
340
+                // 添加查询执行语句到mysql缓存表
341
+                model('SqlCacheTable')->InsertSqlCacheTable();
342
+                // ---------end
343
+                adminLog('新增图集:'.$data['title']);
344
+
345
+                // 生成静态页面代码
346
+                $successData = [
347
+                    'aid'   => $aid,
348
+                    'tid'   => $post['typeid'],
349
+                ];
350
+                $this->success("操作成功!", null, $successData);
351
+                exit;
352
+            }
353
+
354
+            $this->error("操作失败!");
355
+            exit;
356
+        }
357
+
358
+        $typeid = input('param.typeid/d', 0);
359
+        $assign_data['typeid'] = $typeid; // 栏目ID
360
+
361
+        // 栏目信息
362
+        $arctypeInfo = Db::name('arctype')->find($typeid);
363
+
364
+        /*允许发布文档列表的栏目*/
365
+        $arctype_html = allow_release_arctype($typeid, array($this->channeltype));
366
+        $assign_data['arctype_html'] = $arctype_html;
367
+        /*--end*/
368
+
369
+        // 阅读权限
370
+        $arcrank_list = get_arcrank_list();
371
+        $assign_data['arcrank_list'] = $arcrank_list;
372
+
373
+        /*模板列表*/
374
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
375
+        $templateList = $archivesLogic->getTemplateList($this->nid);
376
+        $this->assign('templateList', $templateList);
377
+        /*--end*/
378
+
379
+        /*默认模板文件*/
380
+        $tempview = 'view_'.$this->nid.'.'.config('template.view_suffix');
381
+        !empty($arctypeInfo['tempview']) && $tempview = $arctypeInfo['tempview'];
382
+        $this->assign('tempview', $tempview);
383
+        /*--end*/
384
+
385
+        // 文档默认浏览量
386
+        $globalConfig = tpCache('global');
387
+        if (isset($globalConfig['other_arcclick']) && 0 <= $globalConfig['other_arcclick']) {
388
+            $arcclick_arr = explode("|", $globalConfig['other_arcclick']);
389
+            if (count($arcclick_arr) > 1) {
390
+                $assign_data['rand_arcclick'] = mt_rand($arcclick_arr[0], $arcclick_arr[1]);
391
+            } else {
392
+                $assign_data['rand_arcclick'] = intval($arcclick_arr[0]);
393
+            }
394
+        }else{
395
+            $arcclick_config['other_arcclick'] = '500|1000';
396
+            tpCache('other', $arcclick_config);
397
+            $assign_data['rand_arcclick'] = mt_rand(500, 1000);
398
+        }
399
+
400
+        // URL模式
401
+        $tpcache = config('tpcache');
402
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
403
+
404
+        /*文档属性*/
405
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
406
+
407
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
408
+        $assign_data['channelRow'] = $channelRow;
409
+
410
+        // 来源列表
411
+        $system_originlist = tpSetting('system.system_originlist');
412
+        $system_originlist = json_decode($system_originlist, true);
413
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
414
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
415
+        $assign_data['system_originlist_0'] = !empty($system_originlist) ? $system_originlist[0] : "";
416
+        // 多站点,当用站点域名访问后台,发布文档自动选择当前所属区域
417
+        model('Citysite')->auto_location_select($assign_data);
418
+
419
+        $this->assign($assign_data);
420
+
421
+        return $this->fetch();
422
+    }
423
+    
424
+    /**
425
+     * 编辑
426
+     */
427
+    public function edit()
428
+    {
429
+        $admin_info = session('admin_info');
430
+        $auth_role_info = $admin_info['auth_role_info'];
431
+        $this->assign('auth_role_info', $auth_role_info);
432
+        $this->assign('admin_info', $admin_info);
433
+
434
+        if (IS_POST) {
435
+            $post = input('post.');
436
+            model('Archives')->editor_auto_210607($post);
437
+            $post['aid'] = intval($post['aid']);
438
+
439
+            /* 处理TAG标签 */
440
+            if (!empty($post['tags_new'])) {
441
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
442
+                unset($post['tags_new']);
443
+            }
444
+            $post['tags'] = explode(',', $post['tags']);
445
+            $post['tags'] = array_unique($post['tags']);
446
+            $post['tags'] = implode(',', $post['tags']);
447
+            /* END */
448
+
449
+            $typeid = input('post.typeid/d', 0);
450
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
451
+
452
+            // 根据标题自动提取相关的关键字
453
+            $seo_keywords = $post['seo_keywords'];
454
+            if (!empty($seo_keywords)) {
455
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
456
+            } else {
457
+                // $seo_keywords = get_split_word($post['title'], $content);
458
+            }
459
+
460
+            // 自动获取内容第一张图片作为封面图
461
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
462
+            $litpic = '';
463
+            if ($is_remote == 1) {
464
+                $litpic = $post['litpic_remote'];
465
+            } else {
466
+                $litpic = $post['litpic_local'];
467
+            }
468
+            if (empty($litpic)) {
469
+                $litpic = get_html_first_imgurl($content);
470
+            }
471
+            $post['litpic'] = $litpic;
472
+
473
+            /*是否有封面图*/
474
+            if (empty($post['litpic'])) {
475
+                $is_litpic = 0; // 无封面图
476
+            } else {
477
+                $is_litpic = !empty($post['is_litpic']) ? $post['is_litpic'] : 0; // 有封面图
478
+            }
479
+
480
+            // 勾选后SEO描述将随正文内容更新
481
+            $basic_update_seo_description = empty($post['basic_update_seo_description']) ? 0 : 1;
482
+            if (is_language()) {
483
+                $langRow = \think\Db::name('language')->order('id asc')
484
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
485
+                    ->select();
486
+                foreach ($langRow as $key => $val) {
487
+                    tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description], $val['mark']);
488
+                }
489
+            } else {
490
+                tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description]);
491
+            }
492
+            /*--end*/
493
+
494
+            // SEO描述
495
+            $seo_description = '';
496
+            if (!empty($basic_update_seo_description) || empty($post['seo_description'])) {
497
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
498
+            } else {
499
+                $seo_description = $post['seo_description'];
500
+            }
501
+
502
+            // --外部链接
503
+            $jumplinks = '';
504
+            $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
505
+            if (intval($is_jump) > 0) {
506
+                $jumplinks = $post['jumplinks'];
507
+            }
508
+
509
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
510
+            if ($post['type_tempview'] == $post['tempview']) {
511
+                unset($post['type_tempview']);
512
+                unset($post['tempview']);
513
+            }
514
+            
515
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
516
+            $htmlfilename = trim($post['htmlfilename']);
517
+            if (!empty($htmlfilename)) {
518
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
519
+                // $htmlfilename = strtolower($htmlfilename);
520
+                //判断是否存在相同的自定义文件名
521
+                $map = [
522
+                    'aid'   => ['NEQ', $post['aid']],
523
+                    'htmlfilename'  => $htmlfilename,
524
+                    'lang'  => $this->admin_lang,
525
+                ];
526
+                if (!empty($post['typeid'])) {
527
+                    $map['typeid'] = array('eq', $post['typeid']);
528
+                }
529
+                $filenameCount = Db::name('archives')->where($map)->count();
530
+                if (!empty($filenameCount)) {
531
+                    $this->error("同栏目下,自定义文件名已存在!");
532
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
533
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
534
+                }
535
+            } else {
536
+                // 处理外贸链接
537
+                if (is_dir('./weapp/Waimao/')) {
538
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
539
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'edit', $this->globalConfig);
540
+                }
541
+            }
542
+            $post['htmlfilename'] = $htmlfilename;
543
+
544
+            // 同步栏目切换模型之后的文档模型
545
+            $channel = Db::name('arctype')->where(['id'=>$typeid])->getField('current_channel');
546
+
547
+            //做未通过审核文档不允许修改文档状态操作
548
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
549
+                $old_archives_arcrank = Db::name('archives')->where(['aid' => $post['aid']])->getField("arcrank");
550
+                if ($old_archives_arcrank < 0) {
551
+                    unset($post['arcrank']);
552
+                }
553
+            }
554
+
555
+            // 副栏目
556
+            if (isset($post['stypeid'])) {
557
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
558
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
559
+                $post['stypeid'] = trim($post['stypeid'], ',');
560
+                $post['stypeid'] = str_replace(",{$typeid},", ',', ",{$post['stypeid']},");
561
+                $post['stypeid'] = trim($post['stypeid'], ',');
562
+            }
563
+
564
+            // --存储数据
565
+            $newData = array(
566
+                'typeid'=> $typeid,
567
+                'channel'   => $channel,
568
+                'is_b'      => empty($post['is_b']) ? 0 : $post['is_b'],
569
+                'is_head'      => empty($post['is_head']) ? 0 : $post['is_head'],
570
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
571
+                'is_recom'      => empty($post['is_recom']) ? 0 : $post['is_recom'],
572
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
573
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
574
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
575
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
576
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
577
+                'is_jump'   => $is_jump,
578
+                'is_litpic'     => $is_litpic,
579
+                'jumplinks' => $jumplinks,
580
+                'seo_keywords'     => $seo_keywords,
581
+                'seo_description'     => $seo_description,
582
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
583
+                'add_time'     => strtotime($post['add_time']),
584
+                'update_time'     => getTime(),
585
+            );
586
+            $data = array_merge($post, $newData);
587
+
588
+            $r = Db::name('archives')->where([
589
+                    'aid'   => $data['aid'],
590
+                    'lang'  => $this->admin_lang,
591
+                ])->update($data);
592
+            
593
+            if ($r) {
594
+                // ---------后置操作
595
+                model('Images')->afterSave($data['aid'], $data, 'edit');
596
+                // ---------end
597
+                adminLog('编辑图集:'.$data['title']);
598
+                
599
+                // 生成静态页面代码
600
+                $successData = [
601
+                    'aid'       => $data['aid'],
602
+                    'tid'       => $typeid,
603
+                ];
604
+                $this->success("操作成功!", null, $successData);
605
+                exit;
606
+            }
607
+
608
+            $this->error("操作失败!");
609
+            exit;
610
+        }
611
+
612
+        $assign_data = array();
613
+
614
+        $id = input('id/d');
615
+        $info = model('Images')->getInfo($id);
616
+        if (empty($info)) {
617
+            $this->error('数据不存在,请联系管理员!');
618
+            exit;
619
+        }
620
+        /*兼容采集没有归属栏目的文档*/
621
+        if (empty($info['channel'])) {
622
+            $channelRow = Db::name('channeltype')->field('id as channel')
623
+                ->where('id',$this->channeltype)
624
+                ->find();
625
+            $info = array_merge($info, $channelRow);
626
+        }
627
+        /*--end*/
628
+        $typeid = $info['typeid'];
629
+        $assign_data['typeid'] = $typeid;
630
+        
631
+        // 副栏目
632
+        $stypeid_arr = [];
633
+        if (!empty($info['stypeid'])) {
634
+            $info['stypeid'] = trim($info['stypeid'], ',');
635
+            $stypeid_arr = Db::name('arctype')->field('id,typename')->where(['id'=>['IN', $info['stypeid']],'is_del'=>0])->select();
636
+        }
637
+        $assign_data['stypeid_arr'] = $stypeid_arr;
638
+
639
+        // 栏目信息
640
+        $arctypeInfo = Db::name('arctype')->find($typeid);
641
+
642
+        $info['channel'] = $arctypeInfo['current_channel'];
643
+        if (is_http_url($info['litpic'])) {
644
+            $info['is_remote'] = 1;
645
+            $info['litpic_remote'] = handle_subdir_pic($info['litpic']);
646
+        } else {
647
+            $info['is_remote'] = 0;
648
+            $info['litpic_local'] = handle_subdir_pic($info['litpic']);
649
+        }
650
+    
651
+        // SEO描述
652
+        // if (!empty($info['seo_description'])) {
653
+        //     $info['seo_description'] = @msubstr(checkStrHtml($info['seo_description']), 0, config('global.arc_seo_description_length'), false);
654
+        // }
655
+
656
+        $assign_data['field'] = $info;
657
+
658
+        // 图集相册
659
+        $imgupload_list = model('ImagesUpload')->getImgUpload($id);
660
+        foreach ($imgupload_list as $key => $val) {
661
+            $imgupload_list[$key]['image_url'] = handle_subdir_pic($val['image_url']); // 支持子目录
662
+        }
663
+        $assign_data['imgupload_list'] = $imgupload_list;
664
+
665
+        /*允许发布文档列表的栏目,文档所在模型以栏目所在模型为主,兼容切换模型之后的数据编辑*/
666
+        $arctype_html = allow_release_arctype($typeid, array($info['channel']));
667
+        $assign_data['arctype_html'] = $arctype_html;
668
+        /*--end*/
669
+
670
+        // 阅读权限
671
+        $arcrank_list = get_arcrank_list();
672
+        $assign_data['arcrank_list'] = $arcrank_list;
673
+
674
+        /*模板列表*/
675
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
676
+        $templateList = $archivesLogic->getTemplateList($this->nid);
677
+        $this->assign('templateList', $templateList);
678
+        /*--end*/
679
+
680
+        /*默认模板文件*/
681
+        $tempview = $info['tempview'];
682
+        empty($tempview) && $tempview = $arctypeInfo['tempview'];
683
+        $this->assign('tempview', $tempview);
684
+        /*--end*/
685
+
686
+        // URL模式
687
+        $tpcache = config('tpcache');
688
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
689
+
690
+        /*文档属性*/
691
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
692
+
693
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
694
+        $assign_data['channelRow'] = $channelRow;
695
+
696
+        // 来源列表
697
+        $system_originlist = tpSetting('system.system_originlist');
698
+        $system_originlist = json_decode($system_originlist, true);
699
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
700
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
701
+
702
+        $this->assign($assign_data);
703
+        return $this->fetch();
704
+    }
705
+    
706
+    /**
707
+     * 删除
708
+     */
709
+    public function del()
710
+    {
711
+        if (IS_POST) {
712
+            $archivesLogic = new \app\admin\logic\ArchivesLogic;
713
+            $archivesLogic->del([], 0, 'images');
714
+        }
715
+    }
716
+
717
+    /**
718
+     * 删除图集相册图
719
+     */
720
+    public function del_imgupload()
721
+    {
722
+        if (IS_POST) {
723
+            $filename= input('filename/s');
724
+            $aid = input('aid/d');
725
+            if (!empty($filename) && !empty($aid)) {
726
+                Db::name('images_upload')->where('image_url','like','%'.$filename)->where('aid',$aid)->delete();
727
+
728
+            }
729
+        }
730
+    }
731
+    //帮助
732
+    public function help()
733
+    {
734
+        $system_originlist = tpSetting('system.system_originlist');
735
+        $system_originlist = json_decode($system_originlist, true);
736
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
737
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
738
+        $this->assign($assign_data);
739
+    
740
+        return $this->fetch();
741
+    }
742
+}

+ 1870
- 0
application/admin/controller/Index.php
File diff suppressed because it is too large
View File


+ 1615
- 0
application/admin/controller/Language.php
File diff suppressed because it is too large
View File


+ 247
- 0
application/admin/controller/Level.php View File

@@ -0,0 +1,247 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+namespace app\admin\controller;
14
+
15
+use think\Page;
16
+use think\Db;
17
+use think\Config;
18
+
19
+class Level extends Base {
20
+
21
+    /**
22
+     * 构造方法
23
+     */
24
+    public function __construct(){
25
+        parent::__construct();
26
+        /*会员中心数据表*/
27
+        $this->users_db        = Db::name('users');         // 会员信息表
28
+        $this->users_money_db  = Db::name('users_money');   // 会员充值表
29
+        $this->users_type_manage_db  = Db::name('users_type_manage');   // 会员等级表
30
+        /*结束*/
31
+
32
+        // 是否开启支付功能设置
33
+        $UsersConfigData = getUsersConfigData('all');
34
+        $this->assign('userConfig',$UsersConfigData);
35
+
36
+        // 模型是否开启
37
+        $channeltype_row = \think\Cache::get('extra_global_channeltype');
38
+        $this->assign('channeltype_row',$channeltype_row);
39
+    }
40
+
41
+    /**
42
+     *  列表
43
+     */
44
+    public function index()
45
+    {
46
+        // 会员级别
47
+        $list = model('UsersLevel')->getList('*', ['is_system'=>0]);
48
+        $this->assign('list',$list);
49
+
50
+        // 会员升级期限
51
+        $member_limit_arr = Config::get('global.admin_member_limit_arr');
52
+        $this->assign('member_limit_arr',$member_limit_arr);
53
+
54
+        // 会员升级产品分类
55
+        $users_type = $this->users_type_manage_db->order('sort_order asc, type_id asc')->select();
56
+        $this->assign('users_type',$users_type);
57
+
58
+        return $this->fetch();
59
+    }
60
+
61
+    /**
62
+     *  会员升级业务列表
63
+     */
64
+    public function upgrade_index()
65
+    {
66
+        // 查询条件
67
+        $where = [
68
+            'a.cause_type' => 0,
69
+            'a.status' => ['IN', [2, 3]],
70
+            'a.lang' => $this->admin_lang,
71
+        ];
72
+
73
+        // 订单号或会员名查询
74
+        $keywords = input('keywords/s');
75
+        if (!empty($keywords)) $where['a.order_number|b.username'] = array('LIKE', "%{$keywords}%");
76
+
77
+        // 支付方式查询
78
+        $pay_method = input('pay_method/s');
79
+        if (!empty($pay_method)) $where['a.pay_method'] = $pay_method;
80
+
81
+        // 会员级别查询
82
+        $level_id = input('level_id/d');
83
+        if (!empty($level_id)) $where['a.level_id'] = $level_id;
84
+
85
+        // 时间检索条件
86
+        $begin = strtotime(input('param.add_time_begin/s'));
87
+        $end = input('param.add_time_end/s');
88
+        !empty($end) && $end .= ' 23:59:59';
89
+        $end = strtotime($end);
90
+        // 时间检索
91
+        if ($begin > 0 && $end > 0) {
92
+            $where['a.add_time'] = array('between', "$begin, $end");
93
+        } else if ($begin > 0) {
94
+            $where['a.add_time'] = array('egt', $begin);
95
+        } else if ($end > 0) {
96
+            $where['a.add_time'] = array('elt', $end);
97
+        }
98
+
99
+        // 分页查询
100
+        $count = $this->users_money_db->alias('a')->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')->where($where)->count();
101
+        $Page = new Page($count, config('paginate.list_rows'));
102
+
103
+        // 数据查询
104
+        $list = $this->users_money_db->field('a.*, b.head_pic, b.username, b.nickname')
105
+            ->alias('a')
106
+            ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
107
+            ->where($where) 
108
+            ->order('a.moneyid desc')
109
+            ->limit($Page->firstRow.','.$Page->listRows)
110
+            ->select();
111
+        foreach ($list as $key => $value) {
112
+            $value['username'] = !empty($value['nickname']) ? $value['nickname'] : $value['username'];
113
+            // 反序列化参数
114
+            $value['cause'] = unserialize($value['cause']);
115
+            $value['head_pic'] = get_head_pic($value['head_pic']);
116
+            $list[$key] = $value;
117
+        }
118
+        $show = $Page->show();
119
+        $this->assign('page', $show);
120
+        $this->assign('list', $list);
121
+        $this->assign('pager', $Page);
122
+
123
+        // 会员等级列表
124
+        $usersLevel = model('UsersLevel')->getList('level_id, level_name', [], 'level_id');
125
+        $this->assign('usersLevel', $usersLevel);
126
+
127
+        // 支付状态
128
+        $pay_status_arr = config('global.pay_status_arr');
129
+        $this->assign('pay_status_arr', $pay_status_arr);
130
+
131
+        // 是否开启文章付费
132
+        $channelRow = Db::name('channeltype')->where('nid', 'in',['article','download'])->getAllWithIndex('nid');
133
+        foreach ($channelRow as &$val){
134
+            if (!empty($val['data'])) $val['data'] = json_decode($val['data'], true);
135
+        }
136
+        $this->assign('channelRow', $channelRow);
137
+        
138
+        return $this->fetch();
139
+    }
140
+    
141
+    /**
142
+     * 删除会员升级
143
+     */
144
+    public function upgrade_del()
145
+    {
146
+        if (IS_POST) {
147
+            $id_arr = input('del_id/a');
148
+            $id_arr = eyIntval($id_arr);
149
+            if(!empty($id_arr)){
150
+                $result = Db::name('users_money')->field('order_number')
151
+                    ->where([
152
+                        'moneyid'    => ['IN', $id_arr],
153
+                        'cause_type'    => 0,
154
+                        'lang'  => $this->admin_lang,
155
+                    ])->select();
156
+                $order_number_list = get_arr_column($result, 'order_number');
157
+
158
+                $r = Db::name('users_money')->where([
159
+                        'moneyid'    => ['IN', $id_arr],
160
+                        'cause_type'    => 0,
161
+                        'lang'  => $this->admin_lang,
162
+                    ])
163
+                    ->cache(true, null, "users_money")
164
+                    ->delete();
165
+                if($r !== false){
166
+                    adminLog('删除会员升级记录:'.implode(',', $order_number_list));
167
+                    $this->success('删除成功');
168
+                }
169
+            }
170
+            $this->error('删除失败');
171
+        }
172
+        $this->error('非法访问');
173
+    }
174
+    
175
+    // 删除
176
+    public function level_type_del()
177
+    {
178
+        $type_id = input('type_id/d');
179
+        if (IS_AJAX_POST && !empty($type_id)) {
180
+            $where = [
181
+                'type_id' => $type_id,
182
+                'lang'    => $this->admin_lang,
183
+            ];
184
+            $type_name_list = $this->users_type_manage_db->where($where)->getField('type_name');
185
+            // 删除会员升级级别
186
+            $return = $this->users_type_manage_db->where($where)->delete();
187
+            if ($return) {
188
+                adminLog('删除会员升级级别:'.$type_name_list);
189
+                $this->success('删除成功');
190
+            }else{
191
+                $this->error('删除失败');
192
+            }
193
+        }
194
+        $this->error('参数有误');
195
+    }
196
+
197
+    // 新增/修改
198
+    public function add_level_data()
199
+    {
200
+        if (IS_POST) {
201
+            $post = input('post.');
202
+
203
+            // 处理新增数据
204
+            $AddLevelData = [];
205
+            foreach ($post['type_name'] as $key => $value) {
206
+                $type_id    = $post['type_id'][$key];
207
+                $type_name  = trim($value);
208
+                $level_id   = $post['level_id'][$key];
209
+                $price      = $post['price'][$key];
210
+                $limit_id   = $post['limit_id'][$key];
211
+                $sort_order = $post['sort_order'][$key];
212
+
213
+                if (empty($type_name))  $this->error('产品名称不可为空');
214
+                if (empty($level_id))   $this->error('会员级别不可为空');
215
+                if (empty($price))      $this->error('产品价格不可为空');
216
+                if (empty($limit_id))   $this->error('会员期限不可为空');
217
+
218
+                $AddLevelData[] = [
219
+                    'type_id'     => $type_id,
220
+                    'type_name'   => $type_name,
221
+                    'level_id'    => $level_id,
222
+                    'price'       => $price,
223
+                    'limit_id'    => $limit_id,
224
+                    'sort_order'  => $sort_order,
225
+                    'update_time' => getTime(),
226
+                ];
227
+
228
+                if (empty($type_id)) {
229
+                    $AddLevelData[$key]['lang']     = $this->admin_lang;
230
+                    $AddLevelData[$key]['add_time'] = getTime();
231
+                    unset($AddLevelData[$key]['type_id']);
232
+                }
233
+            }
234
+
235
+            if (!empty($AddLevelData)) {
236
+                $ReturnId = model('UsersTypeManage')->saveAll($AddLevelData);
237
+            }
238
+
239
+            // 返回
240
+            if (!empty($ReturnId)) {
241
+                $this->success('保存成功');
242
+            }else{
243
+                $this->error('保存失败');
244
+            }
245
+        }
246
+    }
247
+}

+ 234
- 0
application/admin/controller/Links.php View File

@@ -0,0 +1,234 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class Links extends Base
21
+{
22
+    public function index()
23
+    {
24
+        $list = array();
25
+        $param = input('param.');
26
+        $keywords = input('keywords/s');
27
+        $keywords = trim($keywords);
28
+        $condition = [];
29
+        // 应用搜索条件
30
+        foreach (['keywords', 'groupid'] as $key) {
31
+            if (isset($param[$key]) && $param[$key] !== '') {
32
+                if ($key == 'keywords') {
33
+                    $condition['a.title'] = array('LIKE', "%{$keywords}%");
34
+                } else {
35
+                    $condition['a.'.$key] = array('eq', trim($param[$key]));
36
+                }
37
+            }
38
+        }
39
+
40
+        // 多语言
41
+        $condition['a.lang'] = array('eq', $this->admin_lang);
42
+        $fields = "a.*,b.group_name";
43
+
44
+        $linksM =  Db::name('links');
45
+        $count = $linksM->alias("a")->join('links_group b',"a.groupid=b.id",'LEFT')->where($condition)->count('a.id');// 查询满足要求的总记录数
46
+        $Page = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
47
+        $list = $linksM->alias("a")->join('links_group b',"a.groupid=b.id",'LEFT')->field($fields)->where($condition)->order('a.sort_order asc, a.id asc')->limit($Page->firstRow.','.$Page->listRows)->select();
48
+
49
+        $show = $Page->show();// 分页显示输出
50
+        $this->assign('page',$show);// 赋值分页输出
51
+        $this->assign('list',$list);// 赋值数据集
52
+        $this->assign('pager',$pager);// 赋值分页对象
53
+
54
+        $links_group = Db::name('links_group')->field('id, group_name')->where(['lang'=>$this->admin_lang])->order('sort_order asc')->select();
55
+        $this->assign('links_group',$links_group);
56
+
57
+        return $this->fetch();
58
+    }
59
+
60
+    /**
61
+     * 添加友情链接
62
+     */
63
+    public function add()
64
+    {
65
+        if (IS_POST) {
66
+            $post = input('post.');
67
+            $post['target'] = !empty($post['target']) ? 1 : 0;
68
+            $post['nofollow'] = !empty($post['nofollow']) ? 1 : 0;
69
+            $post['url'] = trim($post['url']);
70
+            $post['url'] = preg_replace('/(<|>|;|\(|\)|\!)/i', '', $post['url']);
71
+            if (empty($post['url'])) {
72
+                $this->error('网址URL不能为空!');
73
+            } else if (filter_var($post['url'], FILTER_VALIDATE_URL) === false) {
74
+                $this->error('网址URL格式不正确!');
75
+            }
76
+            $post['title'] = trim($post['title']);
77
+            if (empty($post['title'])) {
78
+                $this->error('网站名称不能为空!');
79
+            }
80
+            // 处理LOGO
81
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
82
+            $logo = '';
83
+            if ($is_remote == 1) {
84
+                $logo = $post['logo_remote'];
85
+            } else {
86
+                $logo = $post['logo_local'];
87
+            }
88
+            $post['logo'] = $logo;
89
+            // --存储数据
90
+            $nowData = array(
91
+                'typeid'    => empty($post['typeid']) ? 1 : $post['typeid'],
92
+                'groupid'    => empty($post['groupid']) ? 1 : $post['groupid'],
93
+                'url'    => $post['url'],
94
+                'lang'  => $this->admin_lang,
95
+                'add_time'    => getTime(),
96
+                'update_time'    => getTime(),
97
+            );
98
+            $data = array_merge($post, $nowData);
99
+            $insertId = Db::name('links')->insertGetId($data);
100
+            if (false !== $insertId) {
101
+                Cache::clear('links');
102
+                adminLog('新增友情链接:'.$post['title']);
103
+                $this->success("操作成功!", url('Links/index'));
104
+            }else{
105
+                $this->error("操作失败!", url('Links/index'));
106
+            }
107
+            exit;
108
+        }
109
+
110
+        $assign_data['group_ids'] = Db::name('links_group')->field('id,group_name,status')->where(['lang'=>$this->admin_lang])->order("sort_order asc, id asc")->select();
111
+
112
+        // 多站点,当用站点域名访问后台,发布文档自动选择当前所属区域
113
+        model('Citysite')->auto_location_select($assign_data);
114
+
115
+        $this->assign($assign_data);
116
+
117
+        return $this->fetch();
118
+    }
119
+    
120
+    /**
121
+     * 编辑友情链接
122
+     */
123
+    public function edit()
124
+    {
125
+        if (IS_POST) {
126
+            $post = input('post.');
127
+            $r = false;
128
+            if(!empty($post['id'])){
129
+                $post['id'] = intval($post['id']);
130
+                $post['target'] = !empty($post['target']) ? 1 : 0;
131
+                $post['nofollow'] = !empty($post['nofollow']) ? 1 : 0;
132
+                $post['url'] = trim($post['url']);
133
+                $post['url'] = preg_replace('/(<|>|;|\(|\)|\!)/i', '', $post['url']);
134
+                if (empty($post['url'])) {
135
+                    $this->error('网址URL不能为空!');
136
+                } else if (filter_var($post['url'], FILTER_VALIDATE_URL) === false) {
137
+                    $this->error('网址URL格式不正确!');
138
+                }
139
+                $post['title'] = trim($post['title']);
140
+                if (empty($post['title'])) {
141
+                    $this->error('网站名称不能为空!');
142
+                }
143
+                // 处理LOGO
144
+                $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
145
+                $logo = '';
146
+                if ($is_remote == 1) {
147
+                    $logo = $post['logo_remote'];
148
+                } else {
149
+                    $logo = $post['logo_local'];
150
+                }
151
+                $post['logo'] = $logo;
152
+                // --存储数据
153
+                $nowData = array(
154
+                    'typeid'    => empty($post['typeid']) ? 1 : $post['typeid'],
155
+                    'groupid'    => empty($post['groupid']) ? 1 : $post['groupid'],
156
+                    'url'    => $post['url'],
157
+                    'update_time'    => getTime(),
158
+                );
159
+                $data = array_merge($post, $nowData);
160
+                $r = Db::name('links')->where([
161
+                        'id'    => $post['id'],
162
+                        'lang'  => $this->admin_lang,
163
+                    ])
164
+                    ->cache(true, null, "links")
165
+                    ->update($data);
166
+            }
167
+            if (false !== $r) {
168
+                adminLog('编辑友情链接:'.$post['title']);
169
+                $this->success("操作成功!",url('Links/index'));
170
+            }else{
171
+                $this->error("操作失败!",url('Links/index'));
172
+            }
173
+            exit;
174
+        }
175
+
176
+        $id = input('id/d');
177
+        $info = Db::name('links')->where([
178
+                'id'    => $id,
179
+                'lang'  => $this->admin_lang,
180
+            ])->find();
181
+        if (empty($info)) {
182
+            $this->error('数据不存在,请联系管理员!');
183
+            exit;
184
+        }
185
+        if (is_http_url($info['logo'])) {
186
+            $info['is_remote'] = 1;
187
+            $info['logo_remote'] = handle_subdir_pic($info['logo']);
188
+        } else {
189
+            $info['is_remote'] = 0;
190
+            $info['logo_local'] = handle_subdir_pic($info['logo']);
191
+        }
192
+
193
+        $group_ids = Db::name('links_group')->field('id,group_name,status')->where(['lang'=>$this->admin_lang])->order("sort_order asc, id asc")->select();
194
+        $this->assign('group_ids',$group_ids);
195
+        $this->assign('info',$info);
196
+
197
+        return $this->fetch();
198
+    }
199
+    
200
+    /**
201
+     * 删除友情链接
202
+     */
203
+    public function del()
204
+    {
205
+        if (IS_POST) {
206
+            $id_arr = input('del_id/a');
207
+            $id_arr = eyIntval($id_arr);
208
+            if(!empty($id_arr)){
209
+                $result = Db::name('links')->field('title')
210
+                    ->where([
211
+                        'id'    => ['IN', $id_arr],
212
+                        'lang'  => $this->admin_lang,
213
+                    ])->select();
214
+                $title_list = get_arr_column($result, 'title');
215
+
216
+                $r = Db::name('links')->where([
217
+                        'id'    => ['IN', $id_arr],
218
+                        'lang'  => $this->admin_lang,
219
+                    ])
220
+                    ->cache(true, null, "links")
221
+                    ->delete();
222
+                if($r){
223
+                    adminLog('删除友情链接:'.implode(',', $title_list));
224
+                    $this->success('删除成功');
225
+                }else{
226
+                    $this->error('删除失败');
227
+                }
228
+            } else {
229
+                $this->error('参数有误');
230
+            }
231
+        }
232
+        $this->error('非法访问');
233
+    }
234
+}

+ 299
- 0
application/admin/controller/LinksGroup.php View File

@@ -0,0 +1,299 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class LinksGroup extends Base
21
+{
22
+    public function index()
23
+    {
24
+        $list = array();
25
+        $keywords = input('keywords/s');
26
+
27
+        $condition = array();
28
+        if (!empty($keywords)) {
29
+            $condition['group_name'] = array('LIKE', "%{$keywords}%");
30
+        }
31
+        $condition['lang'] = array('eq', $this->admin_lang);
32
+
33
+        $linksgroupsM =  Db::name('links_group');
34
+        $count = $linksgroupsM->where($condition)->count('id');// 查询满足要求的总记录数
35
+        $Page = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
36
+        $list = $linksgroupsM->where($condition)->order('sort_order asc, id asc')->limit($Page->firstRow.','.$Page->listRows)->select();
37
+        $min_group_id = 0;
38
+        foreach ($list as $key => $val) {
39
+            if ($min_group_id > $val['id'] || empty($min_group_id)) {
40
+                $min_group_id = $val['id'];
41
+            }
42
+        }
43
+        $this->assign('min_group_id',$min_group_id);
44
+
45
+        /*多语言模式下,分组ID显示主体语言的ID*/
46
+        $main_group_list = [];
47
+        if ($this->admin_lang != $this->main_lang && empty($this->globalConfig['language_split'])) {
48
+            $attr_values = get_arr_column($list, 'id');
49
+            $languageAttrRow = Db::name('language_attr')->field('attr_name,attr_value')->where([
50
+                    'attr_value'    => ['IN', $attr_values],
51
+                    'attr_group'    => 'links_group',
52
+                    'lang'          => $this->admin_lang,
53
+                ])->getAllWithIndex('attr_value');
54
+            $groupids = [];
55
+            foreach ($languageAttrRow as $key => $val) {
56
+                $gid_tmp = str_replace('linksgroup', '', $val['attr_name']);
57
+                array_push($groupids, intval($gid_tmp));
58
+            }
59
+            $main_GroupRow = Db::name('links_group')->field("id,CONCAT('linksgroup', id) AS attr_name")
60
+                ->where([
61
+                    'id'    => ['IN', $groupids],
62
+                    'lang'  => $this->main_lang,
63
+                ])->getAllWithIndex('attr_name');
64
+            foreach ($list as $key => $val) {
65
+                $key_tmp = !empty($languageAttrRow[$val['id']]['attr_name']) ? $languageAttrRow[$val['id']]['attr_name'] : '';
66
+                $main_group_list[$val['id']] = [
67
+                    'id'        => !empty($main_GroupRow[$key_tmp]['id']) ? $main_GroupRow[$key_tmp]['id'] : 0,
68
+                ];
69
+            }
70
+        }
71
+        $this->assign('main_group_list', $main_group_list);
72
+        /*end*/
73
+
74
+        $show = $Page->show();// 分页显示输出
75
+        $this->assign('page',$show);// 赋值分页输出
76
+        $this->assign('list',$list);// 赋值数据集
77
+        $this->assign('pager',$pager);// 赋值分页对象
78
+        return $this->fetch();
79
+    }
80
+
81
+    /**
82
+     * 保存友情链接分组
83
+     */
84
+    public function linksgroup_save()
85
+    {
86
+        if (IS_AJAX_POST) {
87
+            $post = input('post.');
88
+
89
+            if (empty($post['group_name'])) {
90
+                $this->error('至少新增一个链接分组!');
91
+            } else {
92
+                $is_empty = true;
93
+                foreach ($post['group_name'] as $key => $val) {
94
+                    $val = trim($val);
95
+                    if (!empty($val)) {
96
+                        $is_empty = false;
97
+                        break;
98
+                    }
99
+                }
100
+                if (true === $is_empty) {
101
+                    $this->error('分组名称不能为空!');
102
+                }
103
+            }
104
+
105
+            // 数据拼装
106
+            $now_time = getTime();
107
+            $addData = $editData = [];
108
+            foreach ($post['group_name'] as $key => $val) {
109
+                $group_name  = trim($val);
110
+                if (!empty($group_name)) {
111
+                    if (empty($post['id'][$key])) {
112
+                        if ($this->admin_lang == $this->main_lang || !empty($this->globalConfig['language_split'])) {
113
+                            $addData[] = [
114
+                                'group_name' => $group_name,
115
+                                'sort_order' => $post['sort_order'][$key] ? :100,
116
+                                'lang' => $this->admin_lang,
117
+                                'add_time' => $now_time,
118
+                                'update_time' => $now_time,
119
+                            ];
120
+                        }
121
+                    } else {
122
+                        $id = intval($post['id'][$key]);
123
+                        $editData[] = [
124
+                            'id' => $id,
125
+                            'group_name' => $group_name,
126
+                            'sort_order' => $post['sort_order'][$key] ? :100,
127
+                            'lang' => $this->admin_lang,
128
+                            'update_time' => $now_time,
129
+                        ];
130
+                    }
131
+                }
132
+            }
133
+
134
+            if (!empty($addData)) {
135
+                $rdata = model('LinksGroup')->saveAll($addData);
136
+                /*多语言*/
137
+                if (is_language()) {
138
+                    foreach ($rdata as $k1 => $v1) {
139
+                        $attr_data = $v1->getData();
140
+                        // 同步分组ID到多语言的模板变量里,添加多语言分组位
141
+                        $this->syn_add_language_linksgroup($attr_data['id']);
142
+                    }
143
+                }
144
+                /*end*/
145
+            }
146
+
147
+            $r = true;
148
+            if (!empty($editData)) {
149
+                $r = model('LinksGroup')->saveAll($editData);
150
+            }
151
+
152
+            if ($r !== false) {
153
+                Cache::clear('links');
154
+                Cache::clear('links_group');
155
+                adminLog('保存链接分组:'.implode(',', $post['group_name']));
156
+                $this->success('操作成功');
157
+            }
158
+        }
159
+        $this->error('操作失败');
160
+    }
161
+
162
+    /**
163
+     * 同步新增分组ID到多语言的模板变量里
164
+     */
165
+    private function syn_add_language_linksgroup($group_id)
166
+    {
167
+        /*单语言情况下不执行多语言代码*/
168
+        if (!is_language() || tpCache('language.language_split')) {
169
+            return true;
170
+        }
171
+        /*--end*/
172
+
173
+        $attr_group = 'links_group';
174
+        $languageRow = Db::name('language')->field('mark')->order('id asc')->select();
175
+        if (!empty($languageRow) && $this->admin_lang == $this->main_lang) { // 当前语言是主体语言,即语言列表最早新增的语言
176
+            $links_group_db = Db::name('links_group');
177
+            $result = $links_group_db->find($group_id);
178
+            $attr_name = 'linksgroup'.$group_id;
179
+            $r = Db::name('language_attribute')->save([
180
+                'attr_title'    => $result['group_name'],
181
+                'attr_name'     => $attr_name,
182
+                'attr_group'    => $attr_group,
183
+                'add_time'      => getTime(),
184
+                'update_time'   => getTime(),
185
+            ]);
186
+            if (false !== $r) {
187
+                $data = [];
188
+                foreach ($languageRow as $key => $val) {
189
+                    /*同步新分组到其他语言分组列表*/
190
+                    if ($val['mark'] != $this->admin_lang) {
191
+                        $addsaveData = $result;
192
+                        $addsaveData['lang']  = $val['mark'];
193
+                        $addsaveData['group_name'] = $val['mark'].$addsaveData['group_name'];
194
+                        unset($addsaveData['id']);
195
+                        $group_id = $links_group_db->insertGetId($addsaveData);
196
+                    }
197
+                    /*--end*/
198
+                    
199
+                    /*所有语言绑定在主语言的ID容器里*/
200
+                    $data[] = [
201
+                        'attr_name' => $attr_name,
202
+                        'attr_value'    => $group_id,
203
+                        'lang'  => $val['mark'],
204
+                        'attr_group'    => $attr_group,
205
+                        'add_time'      => getTime(),
206
+                        'update_time'   => getTime(),
207
+                    ];
208
+                    /*--end*/
209
+                }
210
+                if (!empty($data)) {
211
+                    model('LanguageAttr')->saveAll($data);
212
+                }
213
+            }
214
+        }
215
+    }
216
+    
217
+    /**
218
+     * 删除友情链接分组
219
+     */
220
+    public function del()
221
+    {
222
+        if (is_language() && empty($this->globalConfig['language_split'])) {
223
+            $this->language_access(); // 多语言功能操作权限
224
+        }
225
+
226
+        $id_arr = input('del_id/a');
227
+        $id_arr = eyIntval($id_arr);
228
+        if(IS_POST && !empty($id_arr)){
229
+            $linksGroupRow = Db::name('links_group')->where(['lang'=>$this->admin_lang])->order('id asc')->column('id');
230
+            if (!empty($linksGroupRow)) {
231
+                if (1 < count($linksGroupRow)) {
232
+                    $firstRow = current($linksGroupRow);
233
+                    $min_group_id = empty($firstRow['id']) ? 0 : $firstRow['id'];
234
+                    if (in_array($min_group_id, $id_arr)) {
235
+                        $this->error('禁止删除默认分组');
236
+                    }
237
+                } else {
238
+                    $this->error('至少保留一个分组');
239
+                }
240
+            }
241
+
242
+            /*多语言*/
243
+            $attr_name_arr = [];
244
+            foreach ($id_arr as $key => $val) {
245
+                $attr_name_arr[] = 'linksgroup'.$val;
246
+            }
247
+            if (is_language() && empty($this->globalConfig['language_split'])) {
248
+                $new_id_arr = Db::name('language_attr')->where([
249
+                        'attr_name' => ['IN', $attr_name_arr],
250
+                        'attr_group'    => 'links_group',
251
+                    ])->column('attr_value');
252
+                !empty($new_id_arr) && $id_arr = $new_id_arr;
253
+            }
254
+            /*--end*/
255
+
256
+            $group_name_list = Db::name('links_group')->where([
257
+                    'id'    => ['IN', $id_arr],
258
+                ])->column('group_name');
259
+
260
+            $r = Db::name('links_group')->where([
261
+                    'id'    => ['IN', $id_arr],
262
+                ])->delete();
263
+            if ($r !== false) {
264
+
265
+                /*删除多语言友情链接分组关联绑定*/
266
+                if (!empty($attr_name_arr)) {
267
+                    if (get_admin_lang() == get_main_lang()) {
268
+                        Db::name('language_attribute')->where([
269
+                                'attr_name' => ['IN', $attr_name_arr],
270
+                                'attr_group'    => 'links_group',
271
+                            ])->delete();
272
+                    }
273
+                    if (empty($this->globalConfig['language_split'])) {
274
+                        Db::name('language_attr')->where([
275
+                                'attr_name' => ['IN', $attr_name_arr],
276
+                                'attr_group'    => 'links_group',
277
+                            ])->delete();
278
+                    } else {
279
+                        Db::name('language_attr')->where([
280
+                                'attr_value' => ['IN', $id_arr],
281
+                                'attr_group'    => 'links_group',
282
+                            ])->delete();
283
+                    }
284
+                }
285
+                /*--end*/
286
+
287
+                Db::name('links')->where([
288
+                    'groupid'    => ['IN', $id_arr],
289
+                ])->delete();
290
+
291
+                Cache::clear('links');
292
+                Cache::clear('links_group');
293
+                adminLog('删除友情链接分组:'.implode(',', $group_name_list));
294
+                $this->success('删除成功');
295
+            }
296
+        }
297
+        $this->error('删除失败');
298
+    }
299
+}

+ 55
- 0
application/admin/controller/Map.php View File

@@ -0,0 +1,55 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+class Map extends Base
17
+{
18
+    public function getLocationByAddress()
19
+    {
20
+        $address =  input('param.address/s');
21
+        $ak      = base64_decode(config('global.baidu_map_ak'));
22
+        $url = $this->request->scheme()."://api.map.baidu.com/geocoder/v2/?address={$address}&city=&output=json&ak={$ak}";
23
+        $result = httpRequest($url);
24
+        $result = json_decode($result, true);
25
+        if (!empty($result) && $result['status'] == 0) {
26
+            $data['lng'] = $result['result']['location']['lng']; // 经度
27
+            $data['lat'] = $result['result']['location']['lat']; // 纬度
28
+            $data['map'] = $data['lng'].','.$data['lat'];
29
+            $this->success('请求成功', null, $data);
30
+        }
31
+
32
+        $this->error('请求失败,无法继续~');
33
+    }
34
+
35
+    public function get_coordinate()
36
+    {
37
+        $coordinate = input('param.coordinate/s');
38
+        $keyword =  input('param.keyword/s');
39
+        $func =  input('param.func/s', 'undefined');
40
+        $lng = 0;
41
+        $lat = 0;
42
+        if($coordinate && strpos($coordinate,',') !== false)
43
+        {
44
+            $map = explode(',',$coordinate);
45
+            $lng = $map[0];
46
+            $lat = isset($map[1]) ? $map[1] : 0;
47
+        }
48
+        $this->assign('lng',$lng);
49
+        $this->assign('lat',$lat);
50
+        $this->assign('ak', base64_decode(config('global.baidu_map_ak')));
51
+        $this->assign('keyword',$keyword);
52
+        $this->assign('func',$func);
53
+        return $this->fetch();
54
+    }
55
+}

+ 875
- 0
application/admin/controller/Media.php View File

@@ -0,0 +1,875 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+
19
+class Media extends Base
20
+{
21
+    public $nid = 'media';
22
+    public $channeltype = '';
23
+
24
+    public function _initialize()
25
+    {
26
+        parent::_initialize();
27
+        $channeltype_list  = config('global.channeltype_list');
28
+        $this->channeltype = $channeltype_list[$this->nid];
29
+        empty($this->channeltype) && $this->channeltype = 5;
30
+        $this->assign('nid', $this->nid);
31
+        $this->assign('channeltype', $this->channeltype);
32
+
33
+        // 返回页面
34
+        $paramTypeid = input('param.typeid/d', 0);
35
+        $this->callback_url = url('Media/index', ['lang' => $this->admin_lang, 'typeid' => $paramTypeid]);
36
+        $this->assign('callback_url', $this->callback_url);
37
+    }
38
+
39
+    //列表
40
+    public function index()
41
+    {
42
+        $this->check_use(); // 验证是否功能版授权
43
+
44
+        $assign_data = $condition = [];
45
+
46
+        // 获取到所有GET参数
47
+        $param = input('param.');
48
+        $typeid = input('typeid/d', 0);
49
+
50
+        // 搜索、筛选查询条件处理
51
+        foreach (['keywords', 'typeid', 'flag', 'is_release','province_id','city_id','area_id'] as $key) {
52
+            if ($key == 'typeid' && empty($param['typeid'])) {
53
+                $typeids = Db::name('arctype')->where('current_channel', $this->channeltype)->column('id');
54
+                $condition['a.typeid'] = array('IN', $typeids);
55
+            }
56
+            if (isset($param[$key]) && $param[$key] !== '') {
57
+                if ($key == 'keywords') {
58
+                    $keywords = $param[$key];
59
+                    $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
60
+                } else if ($key == 'typeid') {
61
+                    $typeid = $param[$key];
62
+                    $hasRow = model('Arctype')->getHasChildren($typeid);
63
+                    $typeids = get_arr_column($hasRow, 'id');
64
+                    // 权限控制 by 小虎哥
65
+                    $admin_info = session('admin_info');
66
+                    if (0 < intval($admin_info['role_id'])) {
67
+                        $auth_role_info = $admin_info['auth_role_info'];
68
+                        if (!empty($typeid) && !empty($auth_role_info) && !empty($auth_role_info['permission']['arctype'])) {
69
+                            $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
70
+                        }
71
+                    }
72
+                    $condition['a.typeid'] = array('IN', $typeids);
73
+                } else if ($key == 'flag') {
74
+                    if ('is_release' == $param[$key]) {
75
+                        $condition['a.users_id'] = array('gt', 0);
76
+                    } else {
77
+                        $FlagNew = $param[$key];
78
+                        $condition['a.'.$param[$key]] = array('eq', 1);
79
+                    }
80
+                } else if (in_array($key, ['province_id','city_id','area_id'])) {
81
+                    if (!empty($param['area_id'])) {
82
+                        $condition['a.area_id'] = $param['area_id'];
83
+                    } else if (!empty($param['city_id'])) {
84
+                        $condition['a.city_id'] = $param['city_id'];
85
+                    } else if (!empty($param['province_id'])) {
86
+                        $condition['a.province_id'] = $param['province_id'];
87
+                    }
88
+                } else {
89
+                    $condition['a.'.$key] = array('eq', $param[$key]);
90
+                }
91
+            }
92
+        }
93
+
94
+        // 权限控制 by 小虎哥
95
+        $admin_info = session('admin_info');
96
+        if (0 < intval($admin_info['role_id'])) {
97
+            $auth_role_info = $admin_info['auth_role_info'];
98
+            if (!empty($auth_role_info) && isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
99
+                $condition['a.admin_id'] = $admin_info['admin_id'];
100
+            }
101
+        }
102
+
103
+        // 时间检索条件
104
+        $begin    = strtotime(input('param.add_time_begin/s'));
105
+        $end    = input('param.add_time_end/s');
106
+        !empty($end) && $end .= ' 23:59:59';
107
+        $end    = strtotime($end);
108
+        if ($begin > 0 && $end > 0) {
109
+            $condition['a.add_time'] = array('between', "$begin, $end");
110
+        } else if ($begin > 0) {
111
+            $condition['a.add_time'] = array('egt', $begin);
112
+        } else if ($end > 0) {
113
+            $condition['a.add_time'] = array('elt', $end);
114
+        }
115
+
116
+        // 必要条件
117
+        $condition['a.channel'] = array('eq', $this->channeltype);
118
+        $condition['a.lang'] = array('eq', $this->admin_lang);
119
+        $condition['a.is_del'] = array('eq', 0);
120
+        $conditionNew = "(a.users_id = 0 OR (a.users_id > 0 AND a.arcrank >= 0))";
121
+
122
+        // 自定义排序
123
+        $orderby = input('param.orderby/s');
124
+        $orderway = input('param.orderway/s');
125
+        if (!empty($orderby) && !empty($orderway)) {
126
+            $orderby = "a.{$orderby} {$orderway}, a.aid desc";
127
+        } else {
128
+            $orderby = "a.aid desc";
129
+        }
130
+
131
+        // 数据查询,搜索出主键ID的值
132
+        $SqlQuery = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->fetchSql()->count('aid');
133
+        $count = Db::name('sql_cache_table')->where(['sql_md5'=>md5($SqlQuery)])->getField('sql_result');
134
+        $count = ($count < 0) ? 0 : $count;
135
+        if (empty($count)) {
136
+            $count = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->count('aid');
137
+            /*添加查询执行语句到mysql缓存表*/
138
+            $SqlCacheTable = [
139
+                'sql_name' => '|media|' . $this->channeltype . '|',
140
+                'sql_result' => $count,
141
+                'sql_md5' => md5($SqlQuery),
142
+                'sql_query' => $SqlQuery,
143
+                'add_time' => getTime(),
144
+                'update_time' => getTime(),
145
+            ];
146
+            if (!empty($FlagNew)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $FlagNew . '|';
147
+            if (!empty($typeid)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $typeid . '|';
148
+            if (!empty($keywords)) $SqlCacheTable['sql_name'] = '|media|keywords|';
149
+            Db::name('sql_cache_table')->insertGetId($SqlCacheTable);
150
+            /*END*/
151
+        }
152
+
153
+        $Page = new Page($count, config('paginate.list_rows'));
154
+        $list = [];
155
+        if (!empty($count)) {
156
+            $limit = $count > config('paginate.list_rows') ? $Page->firstRow.','.$Page->listRows : $count;
157
+            $list = Db::name('archives')
158
+                ->field("a.aid")
159
+                ->alias('a')
160
+                ->where($condition)
161
+                ->where($conditionNew)
162
+                ->order($orderby)
163
+                ->limit($limit)
164
+                ->getAllWithIndex('aid');
165
+            if (!empty($list)) {
166
+                $aids = array_keys($list);
167
+                $fields = "b.*, a.*, a.aid as aid";
168
+                $row = Db::name('archives')
169
+                    ->field($fields)
170
+                    ->alias('a')
171
+                    ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
172
+                    ->where('a.aid', 'in', $aids)
173
+                    ->getAllWithIndex('aid');
174
+                foreach ($list as $key => $val) {
175
+                    $row[$val['aid']]['arcurl'] = get_arcurl($row[$val['aid']]);
176
+                    $row[$val['aid']]['litpic'] = handle_subdir_pic($row[$val['aid']]['litpic']);
177
+                    $list[$key] = $row[$val['aid']];
178
+                }
179
+            }
180
+        }
181
+
182
+        $show = $Page->show();
183
+        $assign_data['page'] = $show;
184
+        $assign_data['list'] = $list;
185
+        $assign_data['pager'] = $Page;
186
+        $assign_data['typeid'] = $typeid;
187
+        $assign_data['tab'] = input('param.tab/d', 3);// 选项卡
188
+        $assign_data['seo_pseudo'] = tpCache('global.seo_pseudo');// 前台URL模式
189
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();// 文档属性
190
+        $assign_data['arctype_info'] = $typeid > 0 ? M('arctype')->field('typename')->find($typeid) : [];// 当前栏目信息
191
+        $this->assign($assign_data);
192
+        return $this->fetch();
193
+    }
194
+
195
+    /**
196
+     * 添加
197
+     */
198
+    public function add()
199
+    {
200
+        $this->check_use(); // 验证是否功能版授权
201
+
202
+        $admin_info = session('admin_info');
203
+        $auth_role_info = $admin_info['auth_role_info'];
204
+        $this->assign('auth_role_info', $auth_role_info);
205
+        $this->assign('admin_info', $admin_info);
206
+
207
+        if (IS_POST) {
208
+            $post    = input('post.');
209
+            model('Archives')->editor_auto_210607($post);
210
+            $post['video'] = htmlspecialchars_decode($post['video']);
211
+            $post['video'] = json_decode($post['video'],true);
212
+            /* 处理TAG标签 */
213
+            if (!empty($post['tags_new'])) {
214
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
215
+                unset($post['tags_new']);
216
+            }
217
+            $post['tags'] = explode(',', $post['tags']);
218
+            $post['tags'] = array_unique($post['tags']);
219
+            $post['tags'] = implode(',', $post['tags']);
220
+            /* END */
221
+
222
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
223
+
224
+            // 根据标题自动提取相关的关键字
225
+            $seo_keywords = $post['seo_keywords'];
226
+            if (!empty($seo_keywords)) {
227
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
228
+            } else {
229
+                // $seo_keywords = get_split_word($post['title'], $content);
230
+            }
231
+
232
+            // 自动获取内容第一张图片作为封面图
233
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
234
+            $litpic    = '';
235
+            if ($is_remote == 1) {
236
+                $litpic = $post['litpic_remote'];
237
+            } else {
238
+                $litpic = $post['litpic_local'];
239
+            }
240
+            if (empty($litpic)) {
241
+                $litpic = get_html_first_imgurl($content);
242
+            }
243
+            $post['litpic'] = $litpic;
244
+
245
+            /*是否有封面图*/
246
+            if (empty($post['litpic'])) {
247
+                $is_litpic = 0; // 无封面图
248
+            } else {
249
+                $is_litpic = 1; // 有封面图
250
+            }
251
+
252
+            // SEO描述
253
+            $seo_description = '';
254
+            if (empty($post['seo_description']) && !empty($content)) {
255
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
256
+            } else {
257
+                $seo_description = $post['seo_description'];
258
+            }
259
+
260
+            // 外部链接跳转
261
+            $jumplinks = '';
262
+            $is_jump   = isset($post['is_jump']) ? $post['is_jump'] : 0;
263
+            if (intval($is_jump) > 0) {
264
+                $jumplinks = $post['jumplinks'];
265
+            }
266
+
267
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
268
+            if ($post['type_tempview'] == $post['tempview']) {
269
+                unset($post['type_tempview']);
270
+                unset($post['tempview']);
271
+            }
272
+
273
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
274
+            $htmlfilename = trim($post['htmlfilename']);
275
+            if (!empty($htmlfilename)) {
276
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
277
+                // $htmlfilename = strtolower($htmlfilename);
278
+                //判断是否存在相同的自定义文件名
279
+                $map = [
280
+                    'htmlfilename'  => $htmlfilename,
281
+                    'lang'  => $this->admin_lang,
282
+                ];
283
+                if (!empty($post['typeid'])) {
284
+                    $map['typeid'] = array('eq', $post['typeid']);
285
+                }
286
+                $filenameCount = Db::name('archives')->where($map)->count();
287
+                if (!empty($filenameCount)) {
288
+                    $this->error("同栏目下,自定义文件名已存在!");
289
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
290
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
291
+                }
292
+            } else {
293
+                // 处理外贸链接
294
+                if (is_dir('./weapp/Waimao/')) {
295
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
296
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'add', $this->globalConfig);
297
+                }
298
+            }
299
+            $post['htmlfilename'] = $htmlfilename;
300
+
301
+            //做自动通过审核判断
302
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
303
+                $post['arcrank'] = -1;
304
+            }
305
+
306
+            // 付费限制模式与之前三个字段 arc_level_id、 users_price、 users_free 组合逻辑兼容
307
+            $restricData = restric_type_logic($post, $this->channeltype);
308
+            if (isset($restricData['code']) && empty($restricData['code'])) {
309
+                $this->error($restricData['msg']);
310
+            }
311
+
312
+            // 副栏目
313
+            if (isset($post['stypeid'])) {
314
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
315
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
316
+                $post['stypeid'] = trim($post['stypeid'], ',');
317
+                $post['stypeid'] = str_replace(",{$post['typeid']},", ',', ",{$post['stypeid']},");
318
+                $post['stypeid'] = trim($post['stypeid'], ',');
319
+            }
320
+
321
+            // --存储数据
322
+            $newData = array(
323
+                'typeid'          => empty($post['typeid']) ? 0 : $post['typeid'],
324
+                'channel'         => $this->channeltype,
325
+                'is_b'            => empty($post['is_b']) ? 0 : $post['is_b'],
326
+                'is_head'         => empty($post['is_head']) ? 0 : $post['is_head'],
327
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
328
+                'is_recom'        => empty($post['is_recom']) ? 0 : $post['is_recom'],
329
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
330
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
331
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
332
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
333
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
334
+                'is_jump'         => $is_jump,
335
+                'is_litpic'       => $is_litpic,
336
+                'jumplinks'       => $jumplinks,
337
+                'origin'      => empty($post['origin']) ? '网络' : $post['origin'],
338
+                'seo_keywords'    => $seo_keywords,
339
+                'seo_description' => $seo_description,
340
+                'admin_id'        => session('admin_info.admin_id'),
341
+                'lang'            => $this->admin_lang,
342
+                'sort_order'      => 100,
343
+                'users_free'      => empty($post['users_free']) ? 0 : $post['users_free'],
344
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
345
+                'add_time'        => strtotime($post['add_time']),
346
+                'update_time'     => getTime(),
347
+            );
348
+            $data    = array_merge($post, $newData);
349
+
350
+            $aid          = Db::name('archives')->insertGetId($data);
351
+            $_POST['aid'] = $aid;
352
+            if ($aid) {
353
+                // ---------后置操作
354
+                model('Media')->afterSave($aid, $data, 'add');
355
+                // 添加查询执行语句到mysql缓存表
356
+                model('SqlCacheTable')->InsertSqlCacheTable();
357
+                // ---------end
358
+                adminLog('新增视频:' . $data['title']);
359
+
360
+                // 生成静态页面代码
361
+                $successData = [
362
+                    'aid' => $aid,
363
+                    'tid' => $post['typeid'],
364
+                ];
365
+                $this->success("操作成功!", null, $successData);
366
+                exit;
367
+            }
368
+
369
+            $this->error("操作失败!");
370
+            exit;
371
+        }
372
+
373
+        $typeid                = input('param.typeid/d', 0);
374
+        $assign_data['typeid'] = $typeid; // 栏目ID
375
+
376
+        // 栏目信息
377
+        $arctypeInfo = Db::name('arctype')->find($typeid);
378
+
379
+        /*允许发布文档列表的栏目*/
380
+        $arctype_html                = allow_release_arctype($typeid, array($this->channeltype));
381
+        $assign_data['arctype_html'] = $arctype_html;
382
+        /*--end*/
383
+
384
+        // 阅读权限
385
+        $arcrank_list                = get_arcrank_list();
386
+        $assign_data['arcrank_list'] = $arcrank_list;
387
+
388
+        /*模板列表*/
389
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
390
+        $templateList  = $archivesLogic->getTemplateList($this->nid);
391
+        $assign_data['templateList'] = $templateList;
392
+        /*--end*/
393
+
394
+        /*默认模板文件*/
395
+        $tempview = 'view_' . $this->nid . '.' . config('template.view_suffix');
396
+        !empty($arctypeInfo['tempview']) && $tempview = $arctypeInfo['tempview'];
397
+        $assign_data['tempview'] = $tempview;
398
+        /*--end*/
399
+
400
+        // URL模式
401
+        $tpcache                   = config('tpcache');
402
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
403
+
404
+        // 系统最大上传视频的大小
405
+        $assign_data['upload_max_filesize'] = upload_max_filesize();
406
+        //视频类型
407
+        $media_type = tpCache('global.media_type');
408
+        $media_type = !empty($media_type) ? $media_type : config('global.media_ext');
409
+        $assign_data['media_type'] = $media_type;
410
+        //文件类型
411
+        $file_type = tpCache('global.file_type');
412
+        $file_type = !empty($file_type) ? $file_type : "zip|gz|rar|iso|doc|xls|ppt|wps";
413
+        $assign_data['file_type'] = $file_type;
414
+
415
+        // 模型配置信息
416
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
417
+        $channelRow['data'] = json_decode($channelRow['data'], true);
418
+        $assign_data['channelRow'] = $channelRow;
419
+        
420
+        // 会员等级信息
421
+        $assign_data['users_level'] = model('UsersLevel')->getList('level_id, level_name, level_value');
422
+
423
+        // 文档默认浏览量
424
+        $globalConfig = tpCache('global');
425
+        if (isset($globalConfig['other_arcclick']) && 0 <= $globalConfig['other_arcclick']) {
426
+            $arcclick_arr = explode("|", $globalConfig['other_arcclick']);
427
+            if (count($arcclick_arr) > 1) {
428
+                $assign_data['rand_arcclick'] = mt_rand($arcclick_arr[0], $arcclick_arr[1]);
429
+            } else {
430
+                $assign_data['rand_arcclick'] = intval($arcclick_arr[0]);
431
+            }
432
+        }else{
433
+            $arcclick_config['other_arcclick'] = '500|1000';
434
+            tpCache('other', $arcclick_config);
435
+            $assign_data['rand_arcclick'] = mt_rand(500, 1000);
436
+        }
437
+
438
+        /*文档属性*/
439
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
440
+
441
+        // 来源列表
442
+        $system_originlist = tpSetting('system.system_originlist');
443
+        $system_originlist = json_decode($system_originlist, true);
444
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
445
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
446
+        $assign_data['system_originlist_0'] = !empty($system_originlist) ? $system_originlist[0] : "";
447
+        // 多站点,当用站点域名访问后台,发布文档自动选择当前所属区域
448
+        model('Citysite')->auto_location_select($assign_data);
449
+
450
+        // 视频章节分组插件
451
+        $is_open_videogroup = 0;
452
+        if (is_dir('./weapp/Videogroup/')) {
453
+            $videogroupLogic = new \weapp\Videogroup\logic\VideogroupLogic;
454
+            $weappData = $videogroupLogic->getWeappData();
455
+            if (!empty($weappData['is_open'])) { // 开启
456
+                $is_open_videogroup = 1;
457
+            }
458
+        }
459
+        $assign_data['is_open_videogroup'] = $is_open_videogroup;
460
+
461
+        $this->assign($assign_data);
462
+        return $this->fetch();
463
+    }
464
+
465
+    /**
466
+     * 编辑
467
+     */
468
+    public function edit()
469
+    {
470
+        $this->check_use(); // 验证是否功能版授权
471
+
472
+        $admin_info = session('admin_info');
473
+        $auth_role_info = $admin_info['auth_role_info'];
474
+        $this->assign('auth_role_info', $auth_role_info);
475
+        $this->assign('admin_info', $admin_info);
476
+
477
+        if (IS_POST) {
478
+            $post    = input('post.');
479
+            model('Archives')->editor_auto_210607($post);
480
+            $post['aid'] = intval($post['aid']);
481
+            $post['video'] = htmlspecialchars_decode($post['video']);
482
+            $post['video'] = json_decode($post['video'],true);
483
+            /* 处理TAG标签 */
484
+            if (!empty($post['tags_new'])) {
485
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
486
+                unset($post['tags_new']);
487
+            }
488
+            $post['tags'] = explode(',', $post['tags']);
489
+            $post['tags'] = array_unique($post['tags']);
490
+            $post['tags'] = implode(',', $post['tags']);
491
+            /* END */
492
+
493
+            $typeid  = input('post.typeid/d', 0);
494
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
495
+
496
+            // 根据标题自动提取相关的关键字
497
+            $seo_keywords = $post['seo_keywords'];
498
+            if (!empty($seo_keywords)) {
499
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
500
+            } else {
501
+                // $seo_keywords = get_split_word($post['title'], $content);
502
+            }
503
+
504
+            // 自动获取内容第一张图片作为封面图
505
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
506
+            $litpic    = '';
507
+            if ($is_remote == 1) {
508
+                $litpic = $post['litpic_remote'];
509
+            } else {
510
+                $litpic = $post['litpic_local'];
511
+            }
512
+            if (empty($litpic)) {
513
+                $litpic = get_html_first_imgurl($content);
514
+            }
515
+            $post['litpic'] = $litpic;
516
+
517
+            /*是否有封面图*/
518
+            if (empty($post['litpic'])) {
519
+                $is_litpic = 0; // 无封面图
520
+            } else {
521
+                $is_litpic = !empty($post['is_litpic']) ? $post['is_litpic'] : 0; // 有封面图
522
+            }
523
+
524
+            // 勾选后SEO描述将随正文内容更新
525
+            $basic_update_seo_description = empty($post['basic_update_seo_description']) ? 0 : 1;
526
+            if (is_language()) {
527
+                $langRow = \think\Db::name('language')->order('id asc')
528
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
529
+                    ->select();
530
+                foreach ($langRow as $key => $val) {
531
+                    tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description], $val['mark']);
532
+                }
533
+            } else {
534
+                tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description]);
535
+            }
536
+            /*--end*/
537
+
538
+            // SEO描述
539
+            $seo_description = '';
540
+            if (!empty($basic_update_seo_description) || empty($post['seo_description'])) {
541
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
542
+            } else {
543
+                $seo_description = $post['seo_description'];
544
+            }
545
+
546
+            // --外部链接
547
+            $jumplinks = '';
548
+            $is_jump   = isset($post['is_jump']) ? $post['is_jump'] : 0;
549
+            if (intval($is_jump) > 0) {
550
+                $jumplinks = $post['jumplinks'];
551
+            }
552
+
553
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
554
+            if ($post['type_tempview'] == $post['tempview']) {
555
+                unset($post['type_tempview']);
556
+                unset($post['tempview']);
557
+            }
558
+
559
+            // 同步栏目切换模型之后的文档模型
560
+            $channel = Db::name('arctype')->where(['id'=>$typeid])->getField('current_channel');
561
+
562
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
563
+            $htmlfilename = trim($post['htmlfilename']);
564
+            if (!empty($htmlfilename)) {
565
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
566
+                // $htmlfilename = strtolower($htmlfilename);
567
+                //判断是否存在相同的自定义文件名
568
+                $map = [
569
+                    'aid'   => ['NEQ', $post['aid']],
570
+                    'htmlfilename'  => $htmlfilename,
571
+                    'lang'  => $this->admin_lang,
572
+                ];
573
+                if (!empty($post['typeid'])) {
574
+                    $map['typeid'] = array('eq', $post['typeid']);
575
+                }
576
+                $filenameCount = Db::name('archives')->where($map)->count();
577
+                if (!empty($filenameCount)) {
578
+                    $this->error("同栏目下,自定义文件名已存在!");
579
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
580
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
581
+                }
582
+            } else {
583
+                // 处理外贸链接
584
+                if (is_dir('./weapp/Waimao/')) {
585
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
586
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'edit', $this->globalConfig);
587
+                }
588
+            }
589
+            $post['htmlfilename'] = $htmlfilename;
590
+
591
+            //做未通过审核文档不允许修改文档状态操作
592
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
593
+                $old_archives_arcrank = Db::name('archives')->where(['aid' => $post['aid']])->getField("arcrank");
594
+                if ($old_archives_arcrank < 0) {
595
+                    unset($post['arcrank']);
596
+                }
597
+            }
598
+
599
+            // 付费限制模式与之前三个字段 arc_level_id、 users_price、 users_free 组合逻辑兼容
600
+            $restricData = restric_type_logic($post, $this->channeltype);
601
+            if (isset($restricData['code']) && empty($restricData['code'])) {
602
+                $this->error($restricData['msg']);
603
+            }
604
+
605
+            // 副栏目
606
+            if (isset($post['stypeid'])) {
607
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
608
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
609
+                $post['stypeid'] = trim($post['stypeid'], ',');
610
+                $post['stypeid'] = str_replace(",{$typeid},", ',', ",{$post['stypeid']},");
611
+                $post['stypeid'] = trim($post['stypeid'], ',');
612
+            }
613
+
614
+            // --存储数据
615
+            $newData = array(
616
+                'typeid'          => $typeid,
617
+                'channel'         => $channel,
618
+                'is_b'            => empty($post['is_b']) ? 0 : $post['is_b'],
619
+                'is_head'         => empty($post['is_head']) ? 0 : $post['is_head'],
620
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
621
+                'is_recom'        => empty($post['is_recom']) ? 0 : $post['is_recom'],
622
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
623
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
624
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
625
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
626
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
627
+                'is_jump'         => $is_jump,
628
+                'is_litpic'       => $is_litpic,
629
+                'jumplinks'       => $jumplinks,
630
+                'seo_keywords'    => $seo_keywords,
631
+                'seo_description' => $seo_description,
632
+                'users_free'      => empty($post['users_free']) ? 0 : $post['users_free'],
633
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
634
+                'add_time'        => strtotime($post['add_time']),
635
+                'update_time'     => getTime(),
636
+            );
637
+            $data    = array_merge($post, $newData);
638
+
639
+            $r = Db::name('archives')->where([
640
+                'aid'  => $data['aid'],
641
+                'lang' => $this->admin_lang,
642
+            ])->update($data);
643
+
644
+            if ($r !== false) {
645
+                // ---------后置操作
646
+                model('Media')->afterSave($data['aid'], $data, 'edit');
647
+                // ---------end
648
+                adminLog('编辑视频:' . $data['title']);
649
+
650
+                // 生成静态页面代码
651
+                $successData = [
652
+                    'aid' => $data['aid'],
653
+                    'tid' => $typeid,
654
+                ];
655
+                $this->success("操作成功!", null, $successData);
656
+                exit;
657
+            }
658
+
659
+            $this->error("操作失败!");
660
+            exit;
661
+        }
662
+
663
+        $assign_data = array();
664
+
665
+        $id   = input('id/d');
666
+        $info = model('Media')->getInfo($id, null, true);
667
+        if (empty($info)) {
668
+            $this->error('数据不存在,请联系管理员!');
669
+            exit;
670
+        }
671
+        /*兼容采集没有归属栏目的文档*/
672
+        if (empty($info['channel'])) {
673
+            $channelRow = Db::name('channeltype')->field('id as channel')
674
+                ->where('id', $this->channeltype)
675
+                ->find();
676
+            $info       = array_merge($info, $channelRow);
677
+        }
678
+        /*--end*/
679
+        $typeid = $info['typeid'];
680
+        $assign_data['typeid'] = $typeid;
681
+        
682
+        // 副栏目
683
+        $stypeid_arr = [];
684
+        if (!empty($info['stypeid'])) {
685
+            $info['stypeid'] = trim($info['stypeid'], ',');
686
+            $stypeid_arr = Db::name('arctype')->field('id,typename')->where(['id'=>['IN', $info['stypeid']],'is_del'=>0])->select();
687
+        }
688
+        $assign_data['stypeid_arr'] = $stypeid_arr;
689
+        
690
+        //视频文件
691
+        $video_file = model('MediaFile')->getMediaFile($id);
692
+        $assign_data['video_file'] = json_encode($video_file);
693
+
694
+        // 栏目信息
695
+        $arctypeInfo = Db::name('arctype')->find($typeid);
696
+
697
+        $info['channel'] = $arctypeInfo['current_channel'];
698
+        if (is_http_url($info['litpic'])) {
699
+            $info['is_remote']     = 1;
700
+            $info['litpic_remote'] = handle_subdir_pic($info['litpic']);
701
+        } else {
702
+            $info['is_remote']    = 0;
703
+            $info['litpic_local'] = handle_subdir_pic($info['litpic']);
704
+        }
705
+
706
+        // SEO描述
707
+        // if (!empty($info['seo_description'])) {
708
+        //     $info['seo_description'] = @msubstr(checkStrHtml($info['seo_description']), 0, config('global.arc_seo_description_length'), false);
709
+        // }
710
+
711
+        $assign_data['field'] = $info;
712
+
713
+        /*允许发布文档列表的栏目,文档所在模型以栏目所在模型为主,兼容切换模型之后的数据编辑*/
714
+        $arctype_html                = allow_release_arctype($typeid, array($info['channel']));
715
+        $assign_data['arctype_html'] = $arctype_html;
716
+        /*--end*/
717
+
718
+        // 阅读权限
719
+        $arcrank_list                = get_arcrank_list();
720
+        $assign_data['arcrank_list'] = $arcrank_list;
721
+
722
+        /*模板列表*/
723
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
724
+        $templateList  = $archivesLogic->getTemplateList($this->nid);
725
+        $assign_data['templateList'] = $templateList;
726
+        /*--end*/
727
+
728
+        /*默认模板文件*/
729
+        $tempview = $info['tempview'];
730
+        empty($tempview) && $tempview = $arctypeInfo['tempview'];
731
+        $assign_data['tempview'] = $tempview;
732
+        /*--end*/
733
+
734
+        // URL模式
735
+        $tpcache                   = config('tpcache');
736
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
737
+
738
+        // 系统最大上传视频的大小
739
+        $assign_data['upload_max_filesize'] = upload_max_filesize();
740
+
741
+        //视频类型
742
+        $media_type = tpCache('global.media_type');
743
+        $media_type = !empty($media_type) ? $media_type : config('global.media_ext');
744
+        $assign_data['media_type'] = $media_type;
745
+        //文件类型
746
+        $file_type = tpCache('global.file_type');
747
+        $file_type = !empty($file_type) ? $file_type : "zip|gz|rar|iso|doc|xls|ppt|wps";
748
+        $assign_data['file_type'] = $file_type;
749
+
750
+        // 模型配置信息
751
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
752
+        $channelRow['data'] = json_decode($channelRow['data'], true);
753
+        $assign_data['channelRow'] = $channelRow;
754
+
755
+        // 会员等级信息
756
+        $assign_data['users_level'] = model('UsersLevel')->getList('level_id, level_name, level_value');
757
+
758
+        /*文档属性*/
759
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
760
+
761
+        // 来源列表
762
+        $system_originlist = tpSetting('system.system_originlist');
763
+        $system_originlist = json_decode($system_originlist, true);
764
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
765
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
766
+
767
+        // 视频章节分组插件
768
+        $is_open_videogroup = 0;
769
+        $video_group_list = [];
770
+        if (is_dir('./weapp/Videogroup/')) {
771
+            $videogroupLogic = new \weapp\Videogroup\logic\VideogroupLogic;
772
+            $weappData = $videogroupLogic->getWeappData();
773
+            if (!empty($weappData['is_open'])) { // 开启
774
+                $is_open_videogroup = 1;
775
+                $video_group_list = Db::name('weapp_videogroup')->field('group_id, group_name')->where(['aid'=>$id,'status'=>1])->order('sort_order asc, group_id asc')->select();
776
+            }
777
+        }
778
+        $assign_data['video_group_list'] = json_encode($video_group_list);
779
+        $assign_data['is_open_videogroup'] = $is_open_videogroup;
780
+
781
+        $this->assign($assign_data);
782
+        return $this->fetch();
783
+    }
784
+
785
+    /**
786
+     * 删除
787
+     */
788
+    public function del()
789
+    {
790
+        if (IS_POST) {
791
+            $archivesLogic = new \app\admin\logic\ArchivesLogic;
792
+            $archivesLogic->del([], 0, 'media');
793
+        }
794
+    }
795
+
796
+    /**
797
+     * 获取七牛云token
798
+     */
799
+/*    public function qiniu_upload()
800
+    {
801
+        if (IS_AJAX_POST) {
802
+            $weappInfo     = Db::name('weapp')->where('code','Qiniuyun')->field('id,status,data')->find();
803
+            if (empty($weappInfo)) {
804
+                $this->error('请先安装配置【七牛云图片加速】插件!', null, ['code'=>-1]);
805
+            } else if (1 != $weappInfo['status']) {
806
+                $this->error('请先启用【七牛云图片加速】插件!', null, ['code'=>-2,'id'=>$weappInfo['id']]);
807
+            } else {
808
+                $Qiniuyun = json_decode($weappInfo['data'], true);
809
+                if (empty($Qiniuyun)) {
810
+                    $this->error('请先配置【七牛云图片加速】插件!', null, ['code'=>-3]);
811
+                } else if (empty($Qiniuyun['domain'])) {
812
+                    $this->error('请先配置【七牛云图片加速】插件中的域名!', null, ['code'=>-3]);
813
+                }
814
+            }
815
+
816
+            //引入七牛云的相关文件
817
+            weapp_vendor('Qiniu.src.Qiniu.Auth', 'Qiniuyun');
818
+            weapp_vendor('Qiniu.src.Qiniu.Storage.UploadManager', 'Qiniuyun');
819
+            require_once ROOT_PATH.'weapp/Qiniuyun/vendor/Qiniu/autoload.php';
820
+
821
+            // 配置信息
822
+            $accessKey = $Qiniuyun['access_key'];
823
+            $secretKey = $Qiniuyun['secret_key'];
824
+            $bucket    = $Qiniuyun['bucket'];
825
+            $domain    = '//'.$Qiniuyun['domain'];
826
+
827
+            // 区域对应的上传URl
828
+            $config = new \Qiniu\Config(null);
829
+            $uphost  = $config->getUpHost($accessKey, $bucket);
830
+            $uphost = str_replace('http://', '//', $uphost);
831
+
832
+            // 生成上传Token
833
+            $auth = new \Qiniu\Auth($accessKey, $secretKey);
834
+            $token = $auth->uploadToken($bucket);
835
+            if ($token) {
836
+                $filePath = UPLOAD_PATH.'media/' . date('Ymd/') . session('admin_id') . '-' . dd2char(date("ymdHis") . mt_rand(100, 999));
837
+                $data = [
838
+                    'token'  => $token,
839
+                    'domain'  => $domain,
840
+                    'uphost'  => $uphost,
841
+                    'filePath'  => $filePath,
842
+                ];
843
+                $this->success('获取token成功!', null, $data);
844
+            } else {
845
+                $this->error('获取token失败!');
846
+            }
847
+        }
848
+
849
+    }*/
850
+
851
+    /**
852
+     * 验证是否功能版授权可用
853
+     * @return [type] [description]
854
+     */
855
+    public function check_use()
856
+    {
857
+        $php_servicemeal = tpCache('global.php_servicemeal');
858
+        if ($php_servicemeal < 1.5) {
859
+            $authori_tips = config('global.authori_tips');
860
+            $authori_tips = base64_decode($authori_tips);
861
+            $this->error($authori_tips);
862
+        }
863
+    }
864
+    //帮助
865
+    public function help()
866
+    {
867
+        $system_originlist = tpSetting('system.system_originlist');
868
+        $system_originlist = json_decode($system_originlist, true);
869
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
870
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
871
+        $this->assign($assign_data);
872
+    
873
+        return $this->fetch();
874
+    }
875
+}

+ 2684
- 0
application/admin/controller/Member.php
File diff suppressed because it is too large
View File


+ 291
- 0
application/admin/controller/Memgift.php View File

@@ -0,0 +1,291 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Config;
17
+use think\Page;
18
+use think\Db;
19
+
20
+class Memgift extends Base
21
+{
22
+
23
+    public function _initialize()
24
+    {
25
+        parent::_initialize();
26
+        $functionLogic = new \app\common\logic\FunctionLogic;
27
+        $functionLogic->validate_authorfile(2);
28
+
29
+        // 积分兑换是否已在用
30
+        $shopLogic = new \app\admin\logic\ShopLogic;
31
+        $useFunc = $shopLogic->useFuncLogic();
32
+        if (!in_array('memgift', $useFunc)) {
33
+            $this->error('内置功能已废弃!');
34
+        }
35
+
36
+        //积分名称
37
+        $score = getUsersConfigData('score');
38
+        $this->score_name = $score['score_name'];
39
+        $this->assign('score', $score);
40
+    }
41
+
42
+    //积分商品列表
43
+    public function index()
44
+    {
45
+        $condition = ['is_del' => 0];
46
+        // 获取到所有GET参数
47
+        $param = input('param.');
48
+        if (isset($param['status']) && is_numeric($param['status'])) {
49
+            $condition['status'] = intval($param['status']);
50
+        }
51
+        if (!empty($param['price1']) && !empty($param['price2'])) {
52
+            $condition['score'] = ['between', $param['price1'] . ',' . $param['price2']];
53
+        } else if (!empty($param['price1'])) {
54
+            $condition['score'] = ['egt', $param['price1']];
55
+        } else if (!empty($param['price2'])) {
56
+            $condition['score'] = ['elt', $param['price2']];
57
+        }
58
+
59
+        $count = Db::name('memgift')->alias('a')->where($condition)->count();// 查询满足要求的总记录数
60
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
61
+        $list = Db::name('memgift')->field('a.*')
62
+            ->alias('a')
63
+            ->where($condition)
64
+            ->order('a.sort_order desc')
65
+            ->limit($Page->firstRow . ',' . $Page->listRows)
66
+            ->select();
67
+
68
+        foreach ($list as $key => $val) {
69
+            $list[$key]['litpic'] = get_default_pic($val['litpic']); // 支持子目录
70
+        }
71
+        $show = $Page->show();// 分页显示输出
72
+        $this->assign('page', $show);// 赋值分页输出
73
+        $this->assign('list', $list);// 赋值数据集
74
+        $this->assign('pager', $Page);// 赋值分页集
75
+
76
+        return $this->fetch();
77
+    }
78
+
79
+    //添加礼物
80
+    public function add()
81
+    {
82
+        if (IS_POST) {
83
+            $post = input('post.');
84
+            if ($post['type'] > 0){
85
+                $post['type_id'] = $post['type'];
86
+                $post['type'] = 2;
87
+            }
88
+            $post['add_time'] = getTime();
89
+            $r = Db::name("memgift")->insert($post);
90
+            if ($r !== false) {
91
+                $this->success("添加成功", url("Memgift/index"));
92
+            } else {
93
+                $this->error("添加失败");
94
+            }
95
+        }
96
+        $users_level = Db::name('users_type_manage')
97
+            ->alias('a')
98
+            ->join('users_level b','a.level_id = b.level_id','left')
99
+            ->where(['a.lang'=>$this->admin_lang])
100
+            ->order('sort_order asc')
101
+            ->field('b.level_name,a.level_id,a.limit_id,a.type_id,a.type_name')
102
+            ->select();
103
+        $limit_arr = Config::get('global.admin_member_limit_arr');
104
+        if (!empty($users_level)){
105
+            foreach ($users_level as &$v){
106
+                $v['level_name'] = $v['level_name'].'('.$limit_arr[$v['limit_id']]['limit_name'].')';
107
+            }
108
+        }
109
+        $this->assign('users_level', $users_level);// 赋值分页集
110
+        return $this->fetch();
111
+    }
112
+
113
+    //编辑礼物
114
+    public function edit()
115
+    {
116
+        if (IS_POST) {
117
+            $post = input('post.');
118
+            $gift_id = intval($post['gift_id']);
119
+            if ($post['type'] > 0){
120
+                $post['type_id'] = $post['type'];
121
+                $post['type'] = 2;
122
+            }
123
+            $post['update_time'] = getTime();
124
+            $r = Db::name("memgift")->where(['gift_id' => $gift_id])->update($post);
125
+            if ($r !== false) {
126
+                $this->success("修改成功", url("Memgift/index"));
127
+            } else {
128
+                $this->error("修改失败");
129
+            }
130
+        }
131
+        $gift_id = input('gift_id/d');
132
+        $info = Db::name('memgift')->alias('a')->where(['gift_id' => $gift_id])->find();
133
+
134
+        $users_level = Db::name('users_type_manage')
135
+            ->alias('a')
136
+            ->join('users_level b','a.level_id = b.level_id','left')
137
+            ->where(['a.lang'=>$this->admin_lang])
138
+            ->order('sort_order asc')
139
+            ->field('b.level_name,a.level_id,a.limit_id,a.type_id,a.type_name')
140
+            ->select();
141
+        $limit_arr = Config::get('global.admin_member_limit_arr');
142
+        if (!empty($users_level)){
143
+            foreach ($users_level as &$v){
144
+                $v['level_name'] = $v['level_name'].'('.$limit_arr[$v['limit_id']]['limit_name'].')';
145
+            }
146
+        }
147
+        $this->assign('users_level', $users_level);
148
+        $this->assign('info', $info);
149
+        return $this->fetch();
150
+    }
151
+
152
+    //兑换列表
153
+    public function gift_exchange_list()
154
+    {
155
+        $condition = [];
156
+        // 获取到所有GET参数
157
+        $param = input('param.');
158
+        if (!empty($param['gift_id'])) {
159
+            $condition['a.gift_id'] = $param['gift_id'];
160
+            $syb = 1;
161
+            $this->assign('syb', $syb);
162
+        }
163
+        $status = input('param.status/s', 0);
164
+        if (!empty($status)) {
165
+            if ($status != -1) {
166
+                $condition['a.status'] = $status;
167
+            } else {
168
+                $condition['a.status'] = 0;
169
+            }
170
+        }
171
+        $keywords = input('param.keywords/s', "");
172
+        if (!empty($keywords)) {
173
+            $condition['b.username|b.nickname'] = $keywords;
174
+        }
175
+        $count = Db::name('memgiftget')->alias('a')->join("users b", "a.users_id = b.users_id", 'left')->where($condition)->count();// 查询满足要求的总记录数
176
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
177
+        $list = Db::name('memgiftget')->field('a.*,b.username,b.nickname,b.head_pic,b.sex,c.type')
178
+            ->alias('a')
179
+            ->join("users b", "a.users_id = b.users_id", 'left')
180
+            ->join("memgift c", "a.gift_id = c.gift_id", 'left')
181
+            ->where($condition)
182
+            ->order('a.gid desc')
183
+            ->limit($Page->firstRow . ',' . $Page->listRows)
184
+            ->select();
185
+
186
+        foreach ($list as $key => $val) {
187
+            $list[$key]['litpic'] = get_default_pic($val['litpic']); // 支持子目录
188
+        }
189
+        $show = $Page->show();// 分页显示输出
190
+        $this->assign('page', $show);// 赋值分页输出
191
+        $this->assign('list', $list);// 赋值数据集
192
+        $this->assign('pager', $Page);// 赋值分页集
193
+        //统计
194
+        $count = Db::name('memgiftget')->field('count(*) as count,status')->group('status')->getAllWithIndex('status');
195
+        $this->assign('count', $count);
196
+
197
+        return $this->fetch();
198
+    }
199
+
200
+    //积分商品发货、退货
201
+    public function give()
202
+    {
203
+        $param = input('param.');
204
+        $gid = !empty($param['gid']) ? $param['gid'] : '';
205
+        $syb = !empty($param['syb']) ? $param['syb'] : '';
206
+        $do = !empty($param['do']) ? $param['do'] : '';
207
+        $row = Db::name("memgiftget")
208
+            ->alias('g')
209
+            ->field("g.*,m.username,t.stock")
210
+            ->join("users m", "m.users_id=g.users_id", "left")
211
+            ->join("memgift t", "t.gift_id=g.gift_id", "left")
212
+            ->where(['g.gid' => $gid])->find();
213
+        $users_id = $row['users_id'];
214
+        $score = $row['score'];
215
+        if ($do == 'give') {        //发货
216
+            Db::name('memgiftget')->where(["gid" => $gid])->update(['status' => 1]);
217
+            Db::name('users_notice')->insert(['title'=>$this->score_name.'兑换商品发货','users_id'=>$users_id,'usernames'=>'','remark'=>'您的'.$this->score_name.'兑换商品发货啦,请注意查收~','add_time'=>getTime(),'update_time'=>getTime()]);
218
+            if (!empty($syb) && $syb == 1) {
219
+                $url = url('Memgift/gift_exchange_list', ['gift_id' => $row['gift_id']]);
220
+            } else {
221
+                $url = url('Memgift/gift_exchange_list');
222
+            }
223
+            $this->success("成功发货!已站内信通知会员", $url);
224
+
225
+        } else {      //退回
226
+            $r = Db::name('users')->where(['users_id' => $users_id])->update(['scores' => Db::raw("scores+" . $score)]);
227
+            if ($r !== false) {
228
+                //日志记录
229
+                $users = Db::name('users')->where('users_id', $users_id)->field('scores,devote')->find();
230
+                $data = [
231
+                    'users_id'    => $users_id,
232
+                    'info'        => "{$this->score_name}兑换取消,{$this->score_name}退回,gid={$gid}",
233
+                    'score'       => '+' . $score,
234
+                    'type'        => 9,
235
+                    'add_time'    => getTime(),
236
+                    'update_time' => getTime(),
237
+                    'current_score' => $users['scores'],
238
+                    'current_devote' => $users['devote'],
239
+                ];
240
+                Db::name('users_score')->insert($data);
241
+
242
+                Db::name('memgift')->where(['gift_id' => $row['gift_id']])->update(['stock' => Db::raw("stock+1"),'gid' => 0]);
243
+                Db::name('memgiftget')->where(['gid' => $gid])->update(['status' => 2]);
244
+
245
+                if (!isset($next)) {
246
+                    Db::name('users_notice')->insert(['title'=>$this->score_name.'兑换商品取消发货','users_id'=>$users_id,'usernames'=>'','remark'=>'您的'.$this->score_name.'兑换商品已取消发货!','add_time'=>getTime(),'update_time'=>getTime()]);
247
+
248
+                    $this->success("成功取消发货!已站内信通知会员", url('Memgift/gift_exchange_list'));
249
+                } else {
250
+                    $url = url('Memgift/del', ['next' => 'ok', 'gift_id' => $row['gift_id']]);
251
+                    echo "<script type='text/javascript'>location.href='{$url}';</script>";
252
+                }
253
+            }
254
+        }
255
+    }
256
+
257
+    //重发
258
+    public function again()
259
+    {
260
+        $param = input('param.');
261
+        $gid = !empty($param['gid']) ? $param['gid'] : '';
262
+        $gift_id = !empty($param['gift_id']) ? $param['gift_id'] : '';
263
+        $r = Db::name("memgift")->where(['gift_id' => $gift_id])->update(['stock' => Db::raw("stock+1")]);
264
+        if ($r !== false) {
265
+            Db::name("memgiftget")->where(['gid' => $gid])->update(['status' => 3]);
266
+
267
+            $this->success("重发成功,该商品库存已补充", url('Memgift/index'));
268
+        } else {
269
+            $this->error("出问题了!");
270
+        }
271
+    }
272
+
273
+    //删除积分商品
274
+    public function del()
275
+    {
276
+        $id_arr = input('del_id/a');
277
+        $id_arr = eyIntval($id_arr);
278
+        if (IS_POST && !empty($id_arr)) {
279
+            $result = Db::name("memgift")->field("giftname")->where(['gift_id' => ['in', $id_arr]])->select();
280
+            $name_list = get_arr_column($result, 'giftname');
281
+
282
+            $r = Db::name("memgift")->where(['gift_id' => ['in', $id_arr]])->cache(true, null, "memgift")
283
+                ->delete();
284
+            if ($r !== false) {
285
+                adminLog('删除区域:' . implode(',', $name_list));
286
+                $this->success('删除成功');
287
+            }
288
+        }
289
+        $this->error('删除失败');
290
+    }
291
+}

+ 369
- 0
application/admin/controller/Navigation.php View File

@@ -0,0 +1,369 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-06-28
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Cache;
19
+use app\admin\model\NavPosition;
20
+use app\common\logic\NavigationLogic;
21
+
22
+
23
+/**
24
+ * 导航管理
25
+ */
26
+class Navigation extends Base
27
+{
28
+
29
+    private $position_model;
30
+    private $list_db;
31
+    private $position_db;
32
+    private $navigationlogic;
33
+
34
+    /**
35
+     * 构造方法
36
+     */
37
+    public function __construct(){
38
+        parent::__construct();
39
+        $this->position_model = new NavPosition;
40
+        $this->list_db = Db::name('nav_list');
41
+        $this->position_db = Db::name('nav_position');
42
+        $this->navigationlogic = new NavigationLogic;
43
+
44
+    }
45
+    //菜单管理页面
46
+    public function index()
47
+    {
48
+        $list = array();
49
+        $position_id = input('position_id/s');
50
+        $map = array();
51
+        if (empty($position_id)) {
52
+            $position_id = $this->position_db->order('position_id asc')->limit(1)->value('position_id');
53
+        }
54
+        $this->assign('position_id', $position_id);
55
+
56
+        $map['c.position_id'] = $position_id;
57
+        $nav_list = $this->navigationlogic->nav_list(0, 0, false, 0, $map, false);
58
+        $this->assign('list', $nav_list);
59
+
60
+        $position_list = $this->position_db->where('is_del',0)->order('sort_order asc,position_id asc')->getAllWithIndex('position_id');
61
+        $this->assign('position_list', $position_list);
62
+
63
+        $web_navigation_switch = tpCache('global.web_navigation_switch');
64
+        $this->assign('web_navigation_switch', intval($web_navigation_switch));
65
+
66
+        /*获取所有有子栏目的栏目id*/
67
+        $parent_ids = Db::name('nav_list')->where([
68
+                'parent_id' => ['gt', 0],
69
+                'is_del'    => 0,
70
+            ])->group('parent_id')->column('parent_id');
71
+        $cookied_treeclicked =  json_decode(cookie('navigation-treeClicked-Arr'));
72
+        empty($cookied_treeclicked) && $cookied_treeclicked = [];
73
+        $all_treeclicked = cookie('navigation-treeClicked_All');
74
+        empty($all_treeclicked) && $all_treeclicked = [];
75
+        $tree = [
76
+            'has_children'=>!empty($parent_ids) ? 1 : 0,
77
+            'parent_ids'=>json_encode($parent_ids),
78
+            'all_treeclicked'=>$all_treeclicked,
79
+            'cookied_treeclicked'=>$cookied_treeclicked,
80
+            'cookied_treeclicked_arr'=>json_encode($cookied_treeclicked),
81
+        ];
82
+        $this->assign('tree', $tree);
83
+        /* end */
84
+
85
+        return $this->fetch('index');
86
+    }
87
+
88
+    /**
89
+     * 插件后台管理 - 列表
90
+     */
91
+    public function navigation_index()
92
+    {
93
+        $map = array();
94
+        $list = array();
95
+        $count = $this->position_db->where($map)->count('position_id');
96
+        $pageObj = new Page($count, config('paginate.list_rows'));
97
+        $list = $this->position_db->where($map)->order('sort_order asc,position_id desc')->limit($pageObj->firstRow.','.$pageObj->listRows)->select();
98
+        $pageStr = $pageObj->show();
99
+        $this->assign('list', $list);
100
+        $this->assign('pageStr', $pageStr);
101
+        $this->assign('pager', $pageObj);
102
+
103
+        return $this->fetch('navigation_index');
104
+    }
105
+
106
+    public function add_position()
107
+    {
108
+        if (IS_POST) {
109
+            $post = input('post.');
110
+            // 导航不可重复
111
+            $PostLevelName = array_unique($post['position_name']);
112
+            if (count($PostLevelName) != count($post['position_name'])) {
113
+                $this->error('导航名称不可重复!');
114
+            }
115
+            // 数据拼装
116
+            $AddUsersLevelData = $where = [];
117
+            foreach ($post['position_name'] as $key => $value) {
118
+                $position_id    = $post['position_id'][$key];
119
+                $sort_order    = !empty($post['sort_order'][$key]) ? $post['sort_order'][$key]:100;
120
+                $position_name  = trim($value);
121
+                if (empty($position_name)) {
122
+                    if (empty($position_id)) {
123
+                        unset($AddUsersLevelData[$key]);
124
+                        continue;
125
+                    }else{
126
+                        $this->error('导航名称不可为空!');
127
+                    }
128
+                }
129
+
130
+                $AddUsersLevelData[$key] = [
131
+                    'position_id'    => $position_id,
132
+                    'position_name'  => $position_name,
133
+                    'sort_order'  => $sort_order,
134
+                    'update_time' => getTime(),
135
+                ];
136
+
137
+                if (empty($position_id)) {
138
+                    $AddUsersLevelData[$key]['lang']     = $this->admin_lang;
139
+                    $AddUsersLevelData[$key]['add_time'] = getTime();
140
+                    unset($AddUsersLevelData[$key]['position_id']);
141
+                }
142
+            }
143
+
144
+            $ReturnId = $this->position_model->saveAll($AddUsersLevelData);
145
+            if ($ReturnId) {
146
+                $position_name = implode(",",$post['position_name']);
147
+                adminLog('新增/编辑导航管理:'.$position_name); // 写入操作日志
148
+                $this->success("操作成功", url('Navigation/index'));
149
+            } else {
150
+                $this->error('操作失败');
151
+            }
152
+        }
153
+    }
154
+    
155
+    /**
156
+     * 插件后台管理 - 新增
157
+     */
158
+    public function add()
159
+    {
160
+        if (IS_AJAX_POST) {
161
+            $post = input('post.');
162
+            if (!empty($post)) {
163
+                if (empty($post['arctype_sync'])) {
164
+                    if (empty($post['nav_name'])) $this->error("请填写导航名称");
165
+                    if (empty($post['nav_url'])) $this->error("请填写导航链接");
166
+                }
167
+                if (!empty($post['parent_id'])){
168
+                    $post['topid'] = Db::name('nav_list')->where('nav_id',$post['parent_id'])->value('topid');
169
+                    if (0 == $post['topid']){
170
+                        $post['topid'] = $post['parent_id'];
171
+                    }
172
+                }
173
+
174
+                /*封面图的本地/远程图片处理*/
175
+                $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
176
+                $litpic = '';
177
+                if (1 == $is_remote) {
178
+                    $litpic = $post['litpic_remote'];
179
+                } else {
180
+                    $litpic = $post['nav_pic'];
181
+                }
182
+                /*--end*/
183
+
184
+                if (!empty($post['type_id'])){
185
+                    $post['arctype_sync'] = 1;
186
+                }
187
+
188
+                // url格式化
189
+                $post['nav_url'] = htmlspecialchars_decode($post['nav_url']);
190
+
191
+                $newData = array(
192
+                    'target'      => !empty($post['target']) ? 1 : 0,
193
+                    'nofollow'    => !empty($post['nofollow']) ? 1 : 0,
194
+                    'is_del'      => 0,
195
+                    'add_time'    => getTime(),
196
+                    'update_time' => getTime()
197
+                );
198
+                $data = array_merge($post, $newData);
199
+                $insertId = $this->list_db->insert($data);
200
+                if (!empty($insertId)) {
201
+                    Cache::clear('nav_list');
202
+                    adminLog('新增导航管理菜单:'.$data['nav_name']); // 写入操作日志
203
+                    $this->success("操作成功", url('Navigation/index', ['position_id'=>$post['position_id']]));
204
+                }
205
+            }
206
+            $this->error("操作失败!");
207
+        }
208
+
209
+        $nav_id = input('nav_id/d', 0);
210
+        $position_id = input('position_id/d', 0);
211
+        // 前台功能下拉框
212
+        $assignData['function'] =  $this->navigationlogic->ForegroundFunction();
213
+        // 全部栏目下拉框
214
+        $assignData['arctypeHtml'] = $this->navigationlogic->getAllArctypeList();
215
+        // 全部导航菜单列表
216
+        $assignData['navListHtml'] = $this->navigationlogic->getAllNavList($position_id, $nav_id);
217
+        $assignData['nav_id'] = $assignData['topid'] = 0;
218
+        if (!empty($nav_id)) {
219
+            $assignData['nav_id'] = intval($nav_id);
220
+            $assignData['topid'] = Db::name('nav_list')->where('nav_id', $nav_id)->getField('topid');
221
+        }
222
+        $this->assign($assignData);
223
+
224
+        $position_name = $this->position_db->where('position_id',$position_id)->value('position_name');
225
+        $this->assign('position_name', $position_name);
226
+        return $this->fetch('add');
227
+    }
228
+    
229
+    /**
230
+     * 插件后台管理 - 编辑
231
+     */
232
+    public function edit()
233
+    {
234
+        if (IS_POST) {
235
+            $post = input('post.');
236
+            if (!empty($post)) {
237
+                $post['nav_id'] = intval($post['nav_id']);
238
+                if (empty($post['type_id'])){
239
+                    if (empty($post['nav_name'])) $this->error("请填写导航名称");
240
+                    if (empty($post['nav_url'])) $this->error("请填写导航链接");
241
+                    $post['arctype_sync'] = 0;
242
+                } else {
243
+                    $post['arctype_sync'] = 1;
244
+                }
245
+
246
+                // url格式化
247
+                $post['nav_url'] = htmlspecialchars_decode($post['nav_url']);
248
+
249
+                $newData = array(
250
+                    'target'      => !empty($post['target']) ? 1 : 0,
251
+                    'nofollow'    => !empty($post['nofollow']) ? 1 : 0,
252
+                    'is_del'      => 0,
253
+                    'update_time' => getTime()
254
+                );
255
+                $data = array_merge($post, $newData);
256
+                $ResultID = $this->list_db->where(['nav_id'=>$data['nav_id']])->cache(true, null, "nav_list")->update($data);
257
+                if($ResultID !== false){
258
+                    adminLog('编辑导航管理菜单:'.$post['nav_name']); // 写入操作日志
259
+                    $this->success("操作成功!", url('Navigation/index', ['position_id'=>$post['position_id']]));
260
+                }
261
+            }
262
+            $this->error("操作失败");
263
+        }
264
+
265
+        $ReturnData = array();
266
+
267
+        $nav_id = input('nav_id/d', 0);
268
+        if (empty($nav_id)) $this->error("请选择导航");
269
+        $field = 'a.*, b.position_name, c.typename';
270
+        $navigList = $this->list_db
271
+            ->field($field)
272
+            ->alias('a')
273
+            ->join('nav_position b', 'a.position_id = b.position_id', 'LEFT')
274
+            ->join('arctype c', 'a.type_id = c.id', 'LEFT')
275
+            ->where('a.nav_id', $nav_id)
276
+            ->find();
277
+        $navigList['nav_name'] = !empty($navigList['arctype_sync']) ? $navigList['typename'] : $navigList['nav_name'];
278
+        $assignData['navigList'] = $navigList;
279
+
280
+        // 前台功能下拉框
281
+        $assignData['function'] =  $this->navigationlogic->ForegroundFunction();
282
+        // 全部栏目下拉框
283
+        $assignData['arctypeHtml'] = $this->navigationlogic->getAllArctypeList($navigList['type_id']);
284
+        // 是否允许修改URL
285
+        $allowUpdate = 1;
286
+        foreach ($assignData['Function'] as $key => $value) {
287
+            if ($navigList['nav_url'] == $value['url']) {
288
+                $allowUpdate = 0; break;
289
+            }
290
+        }
291
+        $assignData['allowUpdate'] = $allowUpdate;
292
+
293
+        $this->assign($assignData);
294
+        return $this->fetch();
295
+    }
296
+    
297
+    /**
298
+     * 删除文档
299
+     */
300
+    public function del()
301
+    {
302
+        $id_arr = input('del_id/a');
303
+        $id_arr = eyIntval($id_arr);
304
+        if(!empty($id_arr) && IS_POST){
305
+            $result = $this->position_db->where("position_id",'IN',$id_arr)->select();
306
+            $title_list = get_arr_column($result, '导航名称');
307
+
308
+            $r = $this->position_db->where("position_id",'IN',$id_arr)->delete();
309
+            if($r !== false){
310
+                $this->list_db->where("position_id",'IN',$id_arr)->cache(true, null, "nav_list")->delete();
311
+                adminLog('删除导航管理:'.implode(',', $title_list));
312
+                $this->success("操作成功!");
313
+            }
314
+        }
315
+        $this->error("操作失败!");
316
+    }
317
+
318
+    /**
319
+     * 删除菜单
320
+     */
321
+    public function list_del()
322
+    {
323
+        $id_arr = input('del_id/a');
324
+        $id_arr = eyIntval($id_arr);
325
+        if(!empty($id_arr) && IS_POST){
326
+            $result = $this->list_db->where("nav_id",'IN',$id_arr)->whereOr("parent_id",'IN',$id_arr)->select();
327
+            $title_list = get_arr_column($result, '导航名称');
328
+            $id_list = get_arr_column($result, 'nav_id');
329
+
330
+            $r = $this->list_db->where("nav_id",'IN',$id_list)->cache(true, null, "nav_list")->delete();
331
+            if($r !== false){
332
+                adminLog('删除导航管理菜单:'.implode(',', $title_list));
333
+                $this->success("操作成功!");
334
+            }
335
+        }
336
+        $this->error("操作失败!");
337
+    }
338
+
339
+    /**
340
+     * 开启/关闭导航模块功能
341
+     * @return [type] [description]
342
+     */
343
+    public function ajax_open_close()
344
+    {
345
+        if (IS_AJAX_POST) {
346
+            $value = input('param.value/d');
347
+            if (1 == $value) {
348
+                $web_navigation_switch = 0;
349
+            } else {
350
+                $web_navigation_switch = 1;
351
+            }
352
+            /*多语言*/
353
+            if (is_language()) {
354
+                $langRow = \think\Db::name('language')->order('id asc')
355
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
356
+                    ->select();
357
+                foreach ($langRow as $key => $val) {
358
+                    tpCache('web', ['web_navigation_switch'=>$web_navigation_switch], $val['mark']);
359
+                }
360
+            } else { // 单语言
361
+                tpCache('web', ['web_navigation_switch'=>$web_navigation_switch]);
362
+            }
363
+            /*--end*/
364
+            $this->success("操作成功");
365
+        }
366
+        $this->error("操作失败");
367
+    }
368
+
369
+}

+ 465
- 0
application/admin/controller/Notice.php View File

@@ -0,0 +1,465 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class Notice extends Base
21
+{
22
+    private $notice_applets_tpl = [];
23
+    private $notice_wechat_tpl = [];
24
+
25
+    public function _initialize() {
26
+        parent::_initialize();
27
+        $this->notice_applets_tpl = [
28
+            7 => ['id' => 855, 'keywords' => [1, 2, 4, 5, 7]], // 订单发货通知
29
+        ];
30
+        $this->notice_wechat_tpl = [
31
+            9 => ['id' => 'OPENTM417958215'], // 订单支付成功通知
32
+        ];
33
+        $this->assign('admin_id', session('admin_id'));
34
+    }
35
+
36
+
37
+    // 基础通知 - 买家通知
38
+    public function buyer_notice()
39
+    {
40
+        // 短信消息模板
41
+        $sms_type = tpCache('sms.sms_type');
42
+        $sms_tplist = Db::name('sms_template')->where(['sms_type'=>$sms_type, 'lang'=>$this->admin_lang])->order('send_scene asc')->select();
43
+        $this->assign('sms_tplist', $sms_tplist);
44
+
45
+        // 邮箱消息模板
46
+        $smtp_tplist = Db::name('smtp_tpl')->where(['lang'=>$this->admin_lang])->order('send_scene asc')->select();
47
+        $this->assign('smtp_tplist', $smtp_tplist);
48
+
49
+        // 微信小程序消息模板
50
+        $applets_tplist = Db::name('applets_template')->where(['lang'=>$this->admin_lang])->order('send_scene asc')->select();
51
+        $this->assign('applets_tplist', $applets_tplist);
52
+
53
+        // 微信小程序消息模板
54
+        $wechat_tplist = Db::name('wechat_template')->where(['lang'=>$this->admin_lang])->order('send_scene asc')->select();
55
+        $this->assign('wechat_tplist', $wechat_tplist);
56
+
57
+        // 站内信消息模板
58
+        $notice_tplist = Db::name('users_notice_tpl')->where(['lang'=>$this->admin_lang])->order('send_scene asc')->select();
59
+        $this->assign('notice_tplist', $notice_tplist);
60
+
61
+        return $this->fetch();
62
+    }
63
+
64
+    public function notice_details_bar()
65
+    {
66
+        // 查询发送类型
67
+        $send_type = input('param.send_type/d', 1);
68
+        $this->assign('send_type', $send_type);
69
+
70
+        // 查询指定的短信模板是否存在
71
+        $sms_type = tpCache('sms.sms_type');
72
+        $sms_where = [
73
+            'sms_type' => $sms_type,
74
+            'lang' => $this->admin_lang,
75
+            'send_scene' => $this->getSmsTplSendSecneID()
76
+        ];
77
+        $notice_sms_tpl = Db::name('sms_template')->where($sms_where)->count();
78
+        $this->assign('notice_sms_tpl', $notice_sms_tpl);
79
+
80
+        // 查询指定的邮箱模板是否存在
81
+        $smtp_where = [
82
+            'lang' => $this->admin_lang,
83
+            'send_scene' => $this->getSmtpTplSendSecneID()
84
+        ];
85
+        $notice_smtp_tpl = Db::name('smtp_tpl')->where($smtp_where)->count();
86
+        $this->assign('notice_smtp_tpl', $notice_smtp_tpl);
87
+
88
+        // 查询指定的微信小程序模板是否存在
89
+        $applets_where = [
90
+            'lang' => $this->admin_lang,
91
+            'send_scene' => $send_type
92
+        ];
93
+        $notice_applets_tpl = Db::name('applets_template')->where($applets_where)->count();
94
+        $this->assign('notice_applets_tpl', $notice_applets_tpl);
95
+
96
+        // 查询指定的微信公众号模板是否存在
97
+        $applets_where = [
98
+            'lang' => $this->admin_lang,
99
+            'send_scene' => $send_type
100
+        ];
101
+        $notice_wechat_tpl = Db::name('wechat_template')->where($applets_where)->count();
102
+        $this->assign('notice_wechat_tpl', $notice_wechat_tpl);
103
+
104
+        // 查询指定的站内信模板是否存在
105
+        $notice_where = [
106
+            'lang' => $this->admin_lang,
107
+            'send_scene' => $this->getNoticeTplSendSecneID()
108
+        ];
109
+        $notice_notice_tpl = Db::name('users_notice_tpl')->where($notice_where)->count();
110
+        $this->assign('notice_notice_tpl', $notice_notice_tpl);
111
+
112
+    }
113
+
114
+    // 短信通知详情
115
+    public function notice_details_sms()
116
+    {
117
+        if (IS_POST) {
118
+            // 是否填写短信配置
119
+            if (1 == $this->globalConfig['sms_type'] && (empty($this->globalConfig['sms_appkey']) || empty($this->globalConfig['sms_secretkey']))) {
120
+                $this->error("请先完善<font color='red'>[基本信息]-[接口API]-[云短信]</font>配置");
121
+            }
122
+            // 是否填写短信配置
123
+            if (2 == $this->globalConfig['sms_type'] && (empty($this->globalConfig['sms_appid_tx']) || empty($this->globalConfig['sms_appkey_tx']))) {
124
+                $this->error("请先完善<font color='red'>[基本信息]-[接口API]-[云短信]</font>配置");
125
+            }
126
+            $post = input('post.');
127
+            $data = [
128
+                'tpl_content' => filter_line_return($post['tpl_content']),
129
+                'update_time' => getTime(),
130
+            ];
131
+            $data = array_merge($post, $data);
132
+            $r = Db::name('sms_template')->where(['tpl_id'=>intval($post['tpl_id'])])->update($data);
133
+            if ($r !== false) {
134
+                $this->success('操作成功');
135
+            }
136
+            $this->error('操作失败');
137
+        }
138
+
139
+        $sms_type = tpCache('sms.sms_type');
140
+        $send_scene = $this->getSmsTplSendSecneID();
141
+        $where = [
142
+            'sms_type' => $sms_type,
143
+            'send_scene' => $send_scene,
144
+            'lang' => $this->admin_lang
145
+        ];
146
+        $info = Db::name('sms_template')->where($where)->find();
147
+        if (empty($info)) $this->error('数据不存在,请联系管理员!');
148
+
149
+        $info['tpl_content_demo'] = '【<签名名称>】' . $info['tpl_content'];
150
+        $info['tpl_content_demo'] = str_replace(['${code}','{1}'], '<订单号>', $info['tpl_content_demo']);
151
+        $info['tpl_content_demo'] = str_replace(['${content}','{1}'], '<订单号>', $info['tpl_content_demo']);
152
+        $this->assign('info', $info);
153
+
154
+        $this->notice_details_bar();
155
+        return $this->fetch();
156
+    }
157
+
158
+    // 邮件通知详情
159
+    public function notice_details_smtp()
160
+    {
161
+        if (IS_POST) {
162
+            $post = input('post.');
163
+            // 是否填写短信配置
164
+            if (empty($post['tpl_title'])) $this->error("请先完善<font color='red'>[基本信息]-[接口API]-[云短信]</font>配置");
165
+            $data = [
166
+                'tpl_title' => filter_line_return($post['tpl_title']),
167
+                'update_time' => getTime(),
168
+            ];
169
+            $data = array_merge($post, $data);
170
+            $r = Db::name('smtp_tpl')->where(['tpl_id'=>intval($post['tpl_id'])])->update($data);
171
+            if ($r !== false) {
172
+                $this->success('操作成功');
173
+            }
174
+            $this->error('操作失败');
175
+        }
176
+
177
+        $send_scene = $this->getSmtpTplSendSecneID();
178
+        $where = [
179
+            'send_scene' => $send_scene,
180
+            'lang' => $this->admin_lang
181
+        ];
182
+        $info = Db::name('smtp_tpl')->where($where)->find();
183
+        if (empty($info)) $this->error('数据不存在,请联系管理员!');
184
+        $this->assign('info', $info);
185
+
186
+        $this->notice_details_bar();
187
+        return $this->fetch();
188
+    }
189
+
190
+    // 微信小程序消息详情
191
+    public function notice_details_applets()
192
+    {
193
+        // 查询指定的微信小程序模板是否存在
194
+        $send_scene = input('param.send_scene/d') ? input('param.send_scene/d') : input('param.send_type/d');
195
+        $where = [
196
+            'lang' => $this->admin_lang,
197
+            'send_scene' => $send_scene
198
+        ];
199
+        $info = Db::name('applets_template')->where($where)->find();
200
+        if (empty($info)) $this->error('数据不存在,请联系管理员!');
201
+        $info['tpl_data'] = !empty($info['tpl_data']) ? json_decode($info['tpl_data'], true) : [];
202
+
203
+        if (IS_POST) {
204
+            // 是否填写微信小程序配置
205
+            $wechat_data = tpSetting("OpenMinicode.conf_weixin");
206
+            $wechat_data = !empty($wechat_data) ? json_decode($wechat_data, true) : [];
207
+            if (empty($wechat_data['appid'])) {
208
+                $this->error("请先完善<font color='red'>[基本信息]-[接口API]-[小程序API]-[微信小程序]</font>配置");
209
+            }
210
+
211
+            if (empty($info['template_code']) || $this->notice_applets_tpl[$send_scene]['id'] != $info['template_code']) {
212
+                $tokenData = get_weixin_access_token(true);
213
+                if (!empty($tokenData['code'])) {
214
+                    // 添加消息模板
215
+                    $url = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=".$tokenData['access_token'];
216
+                    $post_data = array(
217
+                        "tid" => $this->notice_applets_tpl[$send_scene]['id'],
218
+                        "kidList" => $this->notice_applets_tpl[$send_scene]['keywords'],
219
+                        "sceneDesc" => !empty($info['tpl_title']) ? $info['tpl_title'] : '用户操作行为通知',
220
+                    );
221
+                    $response = httpRequest($url, 'POST', $post_data);
222
+                    $params = json_decode($response, true);
223
+                    if (!empty($params['priTmplId'])) {
224
+                        $update = [
225
+                            'template_code' => $this->notice_applets_tpl[$send_scene]['id'],
226
+                            'template_id' => $params['priTmplId'],
227
+                        ];
228
+                        $result = Db::name('applets_template')->where(['send_scene'=>$send_scene])->update($update);
229
+                        if (empty($result)) $this->error('保存失败');
230
+
231
+                        // 删除旧的消息模板
232
+                        $url = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=".$tokenData['access_token'];
233
+                        $post_data = array(
234
+                            "priTmplId" => $info['template_id'],
235
+                        );
236
+                        httpRequest($url, 'POST', $post_data);
237
+                    } else {
238
+                        $msg = !empty($params['errmsg']) ? $params['errmsg'] : '保存失败';
239
+                        $this->error($msg);
240
+                    }
241
+                } else {
242
+                    $this->error($tokenData['msg']);
243
+                }
244
+            }
245
+
246
+            $post = input('post.');
247
+            $update = [
248
+                'is_open' => intval($post['is_open']),
249
+                'update_time' => getTime(),
250
+            ];
251
+            $result = Db::name('applets_template')->where(['tpl_id'=>intval($post['tpl_id'])])->update($update);
252
+            if (!empty($result)) $this->success('操作成功');
253
+            $this->error('操作失败');
254
+        }
255
+
256
+        $this->assign('info', $info);
257
+        $this->notice_details_bar();
258
+        return $this->fetch();
259
+    }
260
+
261
+    // 微信公众号消息详情
262
+    public function notice_details_wechat()
263
+    {
264
+        // 查询指定的微信小程序模板是否存在
265
+        $send_scene = input('param.send_scene/d') ? input('param.send_scene/d') : input('param.send_type/d');
266
+        $where = [
267
+            'lang' => $this->admin_lang,
268
+            'send_scene' => $send_scene
269
+        ];
270
+        $info = Db::name('wechat_template')->where($where)->find();
271
+        if (empty($info)) $this->error('数据不存在,请联系管理员!');
272
+        $info['tpl_data'] = !empty($info['tpl_data']) ? json_decode($info['tpl_data'], true) : [];
273
+
274
+        if (IS_POST) {
275
+            // 是否填写微信公众号配置
276
+            $wechat_data = tpSetting("OpenMinicode.conf_wechat");
277
+            $wechat_data = !empty($wechat_data) ? json_decode($wechat_data, true) : [];
278
+            if (empty($wechat_data['appid'])) {
279
+                $this->error("请先完善<font color='red'>[基本信息]-[接口API]-[微信公众号]</font>配置");
280
+            }
281
+
282
+            if (empty($info['template_code']) || $this->notice_wechat_tpl[$send_scene]['id'] != $info['template_code']) {
283
+                $tokenData = get_wechat_access_token();
284
+                if (!empty($tokenData['code'])) {
285
+                    // 添加消息模板
286
+                    $url = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=".$tokenData['access_token'];
287
+                    $post_data = array(
288
+                        'template_id_short' => $this->notice_wechat_tpl[$send_scene]['id'],
289
+                    );
290
+                    $response = httpRequest($url, 'POST', json_encode($post_data, JSON_UNESCAPED_UNICODE));
291
+                    $params = json_decode($response, true);
292
+                    if (!empty($params['template_id'])) {
293
+                        $update = [
294
+                            'template_code' => $this->notice_wechat_tpl[$send_scene]['id'],
295
+                            'template_id' => $params['template_id'],
296
+                        ];
297
+                        $result = Db::name('wechat_template')->where(['send_scene'=>$send_scene])->update($update);
298
+                        if (empty($result)) $this->error('保存失败');
299
+
300
+                        // 删除旧的消息模板
301
+                        $url = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token=".$tokenData['access_token'];
302
+                        $post_data = array(
303
+                            "template_id" => $info['template_id'],
304
+                        );
305
+                        httpRequest($url, 'POST', $post_data);
306
+                    } else {
307
+                        $msg = !empty($params['errmsg']) ? $params['errmsg'] : '保存失败';
308
+                        $this->error($msg);
309
+                    }
310
+                } else {
311
+                    $this->error($tokenData['msg']);
312
+                }
313
+            }
314
+
315
+            $post = input('post.');
316
+            $update = [
317
+                'is_open' => intval($post['is_open']),
318
+                'update_time' => getTime(),
319
+            ];
320
+            $result = Db::name('wechat_template')->where(['tpl_id'=>intval($post['tpl_id'])])->update($update);
321
+            if (!empty($result)) $this->success('操作成功');
322
+            $this->error('操作失败');
323
+        }
324
+
325
+        $this->assign('info', $info);
326
+        $this->notice_details_bar();
327
+        return $this->fetch();
328
+    }
329
+
330
+    public function notice_details_notice()
331
+    {
332
+        if (IS_POST) {
333
+            $post = input('post.');
334
+            // 是否填写短信配置
335
+            if (empty($post['tpl_title'])) $this->error("站内信标题不能为空!");
336
+            $data = [
337
+                'tpl_title' => filter_line_return($post['tpl_title']),
338
+                'update_time' => getTime(),
339
+            ];
340
+            $data = array_merge($post, $data);
341
+            $r = Db::name('users_notice_tpl')->where(['tpl_id'=>intval($post['tpl_id'])])->update($data);
342
+            if ($r !== false) {
343
+                $this->success('操作成功');
344
+            }
345
+            $this->error('操作失败');
346
+        }
347
+
348
+        $send_scene = $this->getNoticeTplSendSecneID();
349
+        $where = [
350
+            'send_scene' => $send_scene,
351
+            'lang' => $this->admin_lang
352
+        ];
353
+        $info = Db::name('users_notice_tpl')->where($where)->find();
354
+        if (empty($info)) $this->error('数据不存在,请联系管理员!');
355
+        $this->assign('info', $info);
356
+
357
+        $this->notice_details_bar();
358
+        return $this->fetch();
359
+    }
360
+
361
+    // 获取短信模板发送场景ID
362
+    private function getSmsTplSendSecneID()
363
+    {
364
+        // 查询发送类型
365
+        $send_scene = -1;
366
+        $send_type = input('param.send_type/d', 1);
367
+        switch ($send_type) {
368
+            // 账号注册
369
+            case '1':
370
+                $send_scene = 0;
371
+                break;
372
+            // 账号登录
373
+            case '2':
374
+                $send_scene = 2;
375
+                break;
376
+            // 手机绑定
377
+            case '4':
378
+                $send_scene = 1;
379
+                break;
380
+            // 找回密码
381
+            case '5':
382
+                $send_scene = 4;
383
+                break;
384
+            // 留言验证
385
+            case '6':
386
+                $send_scene = 7;
387
+                break;
388
+            // 订单发货
389
+            case '7':
390
+                $send_scene = 6;
391
+                break;
392
+            // 留言表单
393
+            case '8':
394
+                $send_scene = 11;
395
+                break;
396
+            // 订单付款
397
+            case '9':
398
+                $send_scene = 5;
399
+                break;
400
+        }
401
+
402
+        return $send_scene;
403
+    }
404
+
405
+    // 获取邮件模板发送场景ID
406
+    private function getSmtpTplSendSecneID()
407
+    {
408
+        // 查询发送类型
409
+        $send_scene = -1;
410
+        $send_type = input('param.send_type/d', 1);
411
+        switch ($send_type) {
412
+            // 账号注册
413
+            case '1':
414
+                $send_scene = 2;
415
+                break;
416
+            // 邮箱绑定
417
+            case '3':
418
+                $send_scene = 3;
419
+                break;
420
+            // 找回密码
421
+            case '5':
422
+                $send_scene = 4;
423
+                break;
424
+            // 订单发货
425
+            case '7':
426
+                $send_scene = 6;
427
+                break;
428
+            // 留言表单
429
+            case '8':
430
+                $send_scene = 1;
431
+                break;
432
+            // 订单付款
433
+            case '9':
434
+                $send_scene = 5;
435
+                break;
436
+        }
437
+
438
+        return $send_scene;
439
+    }
440
+
441
+    // 获取站内信模板发送场景ID
442
+    private function getNoticeTplSendSecneID()
443
+    {
444
+        // 查询发送类型
445
+        $send_scene = -1;
446
+        $send_type = input('param.send_type/d', 1);
447
+        switch ($send_type) {
448
+            // 订单发货
449
+            case '7':
450
+                $send_scene = 6;
451
+                break;
452
+            // 留言表单
453
+            case '8':
454
+                $send_scene = 1;
455
+                break;
456
+            // 订单付款
457
+            case '9':
458
+                $send_scene = 5;
459
+                break;
460
+        }
461
+
462
+        return $send_scene;
463
+    }
464
+
465
+}

+ 84
- 0
application/admin/controller/Notify.php View File

@@ -0,0 +1,84 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+namespace app\admin\controller;
14
+
15
+use think\Db;
16
+use think\Page;
17
+
18
+class Notify extends Base {
19
+
20
+    /**
21
+     * 构造方法
22
+     */
23
+    public function __construct() {
24
+        parent::__construct();
25
+        // 邮件通知配置
26
+        $this->smtp_tpl_db      = Db::name('smtp_tpl');
27
+        // 短信通知配置
28
+        $this->sms_template_db  = Db::name('sms_template');
29
+        // 站内信配置
30
+        $this->users_notice_tpl_db = Db::name('users_notice_tpl');
31
+        // 站内信通知记录表
32
+        $this->users_notice_tpl_content_db = Db::name('users_notice_tpl_content');
33
+    }
34
+
35
+    /**
36
+     * 站内信模板列表
37
+     */
38
+    public function notify_tpl()
39
+    {
40
+        $list = array();
41
+        $keywords = input('keywords/s');
42
+
43
+        $map = array();
44
+        if (!empty($keywords)) {
45
+            $map['tpl_name'] = array('LIKE', "%{$keywords}%");
46
+        }
47
+
48
+        // 多语言
49
+        $map['lang'] = array('eq', $this->admin_lang);
50
+
51
+        $count = $this->users_notice_tpl_db->where($map)->count('tpl_id');// 查询满足要求的总记录数
52
+        $pageObj = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
53
+        $list = $this->users_notice_tpl_db->where($map)
54
+            ->order('tpl_id asc')
55
+            ->limit($pageObj->firstRow.','.$pageObj->listRows)
56
+            ->select();
57
+        $pageStr = $pageObj->show(); // 分页显示输出
58
+        $this->assign('list', $list); // 赋值数据集
59
+        $this->assign('page', $pageStr); // 赋值分页输出
60
+        $this->assign('pager', $pageObj); // 赋值分页对象
61
+
62
+        $shop_open = getUsersConfigData('shop.shop_open');
63
+        $this->assign('shop_open', $shop_open);
64
+
65
+        return $this->fetch();
66
+    }
67
+
68
+    // 统计未读的站内信数量
69
+    public function count_unread_notify()
70
+    {
71
+        \think\Session::pause(); // 暂停session,防止session阻塞机制
72
+        $notice_where = [
73
+            'is_read' => 0,
74
+            'admin_id' => ['>', 0],
75
+        ];
76
+        $notice_count = $this->users_notice_tpl_content_db->where($notice_where)->count('content_id');
77
+        $notice_count = intval($notice_count);
78
+        if (IS_AJAX) {
79
+            $this->success('查询成功', null, ['notice_count'=>$notice_count]);
80
+        } else {
81
+            $this->assign('notice_count', $notice_count);
82
+        }
83
+    }
84
+}

+ 767
- 0
application/admin/controller/Order.php View File

@@ -0,0 +1,767 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Config;
19
+
20
+class Order extends Base
21
+{
22
+    public function _initialize() {
23
+        parent::_initialize();
24
+    }
25
+
26
+    public function index()
27
+    {
28
+        // 商城中心开启状态
29
+        $shopOpen = getUsersConfigData('shop.shop_open');
30
+        // 会员中心开启状态
31
+        $webUsersSwitch = tpCache('global.web_users_switch');
32
+        // 如果商城中心开启则执行跳转到商城中心,默认待发货订单列表
33
+        if (!empty($shopOpen) && 1 === intval($shopOpen) && 1 == is_check_access('Shop@index')) {
34
+            $url = url('Shop/index', ["order_status"=>1], true, true);
35
+            $url = preg_replace('/^http(s?)/i', $this->request->scheme(), $url);
36
+            $this->redirect($url);
37
+            exit;
38
+        }
39
+        // 如果商城中心未开启,会员中心开启已开启则执行跳转到会员充值订单列表
40
+        else if (!empty($webUsersSwitch) && 1 === intval($webUsersSwitch) && 1 == is_check_access('Member@money_index')) {
41
+            $url = url('Member/money_index', ['status'=>2], true, true);
42
+            $url = preg_replace('/^http(s?)/i', $this->request->scheme(), $url);
43
+            $this->redirect($url);
44
+            exit;
45
+        } else {
46
+            $this->error('您没有操作权限,请联系超级管理员分配权限');
47
+        }
48
+        // 其他逻辑待添加...
49
+
50
+    }
51
+
52
+    // AJAX下载订单Excel文档
53
+    public function ajax_order_excel_export()
54
+    {
55
+        // 设置最大内存
56
+        ini_set("memory_limit", "-1");
57
+
58
+        // 防止php超时
59
+        function_exists('set_time_limit') && set_time_limit(0);
60
+
61
+        if (file_exists('./vendor/PHPExcel.zip') && !is_dir('./vendor/PHPExcel/')) {
62
+            $zip = new \ZipArchive();//新建一个ZipArchive的对象
63
+            if ($zip->open(ROOT_PATH.'vendor'.DS.'PHPExcel.zip') === true) {
64
+                $zip->extractTo(ROOT_PATH.'vendor'.DS.'PHPExcel'.DS);
65
+                $zip->close();//关闭处理的zip文件
66
+                if (is_dir('./vendor/PHPExcel/')) {
67
+                    @unlink('./vendor/PHPExcel.zip');
68
+                }
69
+            }
70
+        }
71
+
72
+        // 执行操作
73
+        if (IS_AJAX_POST) {
74
+            $post = input('post.');
75
+            $ResultUrl = null;
76
+            if (1 == $post['export_type']) {
77
+                // 查询商城订单并处理
78
+                $ExportData = $this->GetShopOrder($post);
79
+            } else if (2 == $post['export_type']) {
80
+                // 查询充值订单并处理
81
+                $ExportData = $this->GetMoneyOrder(1, $post);
82
+            } else if (3 == $post['export_type']) {
83
+                // 查询升级订单并处理
84
+                $ExportData = $this->GetMoneyOrder(0, $post);
85
+            } else if (4 == $post['export_type']) {
86
+                // 查询视频订单并处理
87
+                $ExportData = $this->GetMediaOrder($post);
88
+            } else if (5 == $post['export_type']) {
89
+                // 查询文章订单并处理
90
+                $ExportData = $this->GetArticleOrder($post);
91
+            } else if (6 == $post['export_type']) {
92
+                // 查询文章订单并处理
93
+                $ExportData = $this->GetServiceOrder($post);
94
+            }
95
+            if (!empty($ExportData['ExcelData'])) {
96
+                // 执行导出下载
97
+                $ResultUrl = $this->PerformExport($ExportData['ExcelData'], $ExportData['ExcelField'], $ExportData['ExcelTitle'], $post['export_type']);
98
+            } else if (isset($ExportData['ExcelData'])) {
99
+                $this->error('没有导出的数据');
100
+            }
101
+        }
102
+
103
+        if (!empty($ResultUrl)) {
104
+            $this->success('正在下载', $ResultUrl);
105
+        } else {
106
+            $this->error('导出失败');
107
+        }
108
+    }
109
+
110
+    // 查询商城订单并处理
111
+    private function GetShopOrder($post = [])
112
+    {
113
+        // 查询条件
114
+        $where = [
115
+            'a.lang' => $this->admin_lang
116
+        ];
117
+
118
+        // 订单号查询
119
+        $order_code = !empty($post['order_code']) ? $post['order_code'] : '';
120
+        if (!empty($order_code)) $where['a.order_code'] = ['LIKE', "%{$order_code}%"];
121
+
122
+        // 支付方式查询
123
+        $pay_name = !empty($post['pay_name']) ? $post['pay_name'] : '';
124
+        if (!empty($pay_name)) $where['a.pay_name'] = $pay_name;
125
+
126
+        // 订单下单终端查询
127
+        $order_terminal = !empty($post['order_terminal']) ? $post['order_terminal'] : 0;
128
+        if (!empty($order_terminal)) $where['a.order_terminal'] = $order_terminal;
129
+        
130
+        // 商品类型查询
131
+        $contains_virtual = !empty($post['contains_virtual']) ? $post['contains_virtual'] : 0;
132
+        if (!empty($contains_virtual)) $where['a.contains_virtual'] = $contains_virtual;
133
+
134
+        // 指定订单状态导出
135
+        $order_status = !empty($post['order_status']) ? $post['order_status'] : 0;
136
+        if (!empty($order_status)) $where['a.order_status'] = 10 == $order_status ? 0 : $order_status;
137
+
138
+        // 根据日期导出
139
+        $start_time = $post['start_time'];
140
+        $end_time = $post['end_time'];
141
+        if (!empty($start_time) && !empty($end_time)) {
142
+            $start_time        = strtotime($start_time);
143
+            $end_time          = strtotime("+1 day", strtotime($end_time)) - 1;
144
+            $where['a.add_time'] = ['between', [$start_time, $end_time]];
145
+        } elseif (!empty($start_time) && empty($end_time)) {
146
+            $start_time        = strtotime($start_time);
147
+            $where['a.add_time'] = ['>=', $start_time];
148
+        } elseif (empty($start_time) && !empty($end_time)) {
149
+            $end_time          = strtotime("+1 day", strtotime($end_time)) - 1;
150
+            $where['a.add_time'] = ['<=', $end_time];
151
+        }
152
+
153
+        // 查询字段
154
+        $Field = 'a.order_id, a.order_code, a.order_status, a.pay_time, a.pay_name, a.express_name, a.express_order, a.consignee, a.order_amount, a.order_total_num, a.province, a.city, a.district, a.address, a.mobile, a.add_time, b.username';
155
+        // 执行查询
156
+        $OrderData = Db::name('shop_order')
157
+            ->alias('a')
158
+            ->field($Field)
159
+            ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
160
+            ->where($where)
161
+            ->order('a.order_id desc')
162
+            ->select();
163
+        if (empty($OrderData) && !empty($order_code)) {
164
+            // 通过商品名称查询订单号
165
+            $where_1['product_name'] = ['LIKE', "%{$order_code}%"];
166
+            $order_details_list = Db::name('shop_order_details')->where($where_1)->order('order_id asc, details_id asc')->select();
167
+            $order_details_list = group_same_key($order_details_list, 'order_id');
168
+            $order_ids = array_keys($order_details_list);
169
+            // 重新查询订单主表
170
+            unset($where['a.order_code']);
171
+            $where['a.order_id'] = ['IN', $order_ids];
172
+            // 订单主表数据查询
173
+            $OrderData = Db::name('shop_order')
174
+                ->alias('a')
175
+                ->field($Field)
176
+                ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
177
+                ->where($where)
178
+                ->order('a.order_id desc')
179
+                ->select();
180
+        } else {
181
+            if (!empty($OrderData)) {
182
+                $order_ids = get_arr_column($OrderData, 'order_id');
183
+                $where_1 = [];
184
+                $where_1['order_id'] = ['IN', $order_ids];
185
+                $order_details_list = Db::name('shop_order_details')->where($where_1)->order('order_id asc, details_id asc')->select();
186
+                $order_details_list = group_same_key($order_details_list, 'order_id');
187
+            }
188
+        }
189
+
190
+        // 获取订单状态,后台专用
191
+        $admin_order_status_arr = Config::get('global.admin_order_status_arr');
192
+        // 获取订单方式名称
193
+        $pay_method_arr = Config::get('global.pay_method_arr');
194
+        // 处理订单导出数据
195
+        $ExcelData = [];
196
+        foreach ($OrderData as $key => $value) {
197
+            // 匹配省、市中文
198
+            $Province = get_province_name($value['province']);
199
+            // 匹配市、县中文
200
+            $City     = get_city_name($value['city']);
201
+            // 匹配县、区、镇中文
202
+            $District = get_area_name($value['district']);
203
+            // 订单商品列表
204
+            $product_name_all = '';
205
+            $order_details_info = !empty($order_details_list[$value['order_id']]) ? $order_details_list[$value['order_id']] : [];
206
+            if (!empty($order_details_info)) {
207
+                foreach ($order_details_info as $k => $v) {
208
+                    if (!empty($product_name_all)) {
209
+                        $product_name_all .= PHP_EOL;
210
+                    }
211
+                    $product_name_all .= $v['product_name']. "\t";
212
+                }
213
+            }
214
+            // 拼装追加数据
215
+            $PushData = [
216
+                // 订单信息
217
+                'order_code'   => $value['order_code']. "\t",
218
+                'product_name'    => $product_name_all,
219
+                'order_num'    => $value['order_total_num'],
220
+                'order_amount' => $value['order_amount'],
221
+                'add_time'     => date('Y-m-d H:i:s', $value['add_time']),
222
+                'order_status' => $admin_order_status_arr[$value['order_status']],
223
+                // 支付信息
224
+                'pay_time' => !empty($value['pay_time']) ? date('Y-m-d H:i:s', $value['pay_time']) : '',
225
+                'pay_name' => in_array($value['order_status'], [1, 2, 3]) ? $pay_method_arr[$value['pay_name']] : '',
226
+                // 快递信息
227
+                'express_name'  => $value['express_name'],
228
+                'express_order' => $value['express_order']. "\t",
229
+                // 会员账号
230
+                'username' => $value['username'],
231
+                // 收货信息
232
+                'consignee' => $value['consignee'],
233
+                'mobile'    => $value['mobile'],
234
+                'addr_info' => $Province . ' ' . $City . ' ' . $District . ' ' . $value['address'],
235
+            ];
236
+            // 追加数据,用于导出
237
+            array_push($ExcelData, $PushData);
238
+        }
239
+        // 导出字段设置
240
+        $ExcelField = ['order_code', 'product_name', 'order_num', 'order_amount', 'add_time', 'order_status', 'pay_time', 'pay_name', 'express_name', 'express_order', 'username', 'consignee', 'mobile', 'addr_info'];
241
+        // 导出标题设置
242
+        $ExcelTitle = ['订单号', '商品名称', '商品数量', '订单总额', '下单时间', '订单状态', '支付时间', '支付方式', '快递公司', '快递单号', '会员账号', '收货人', '联系电话', '收货地址'];
243
+
244
+        // 返回导出所需数据及参数
245
+        $ReturnData = [
246
+            'ExcelData' => $ExcelData,
247
+            'ExcelField' => $ExcelField,
248
+            'ExcelTitle' => $ExcelTitle
249
+        ];
250
+        return $ReturnData;
251
+    }
252
+
253
+    // 查询充值订单并处理
254
+    private function GetMoneyOrder($cause_type = 0, $post = [])
255
+    {
256
+        // 查询条件
257
+        $where = [
258
+            // 多语言
259
+            'a.lang' => $this->admin_lang,
260
+            // 查询充值订单
261
+            'a.cause_type' => $cause_type
262
+        ];
263
+
264
+        // 订单号或会员名查询
265
+        $keywords = !empty($post['keywords']) ? $post['keywords'] : '';
266
+        if (!empty($keywords)) $where['a.order_number|b.username'] = array('LIKE', "%{$keywords}%");
267
+
268
+        // 支付方式查询
269
+        $pay_method = !empty($post['pay_method']) ? $post['pay_method'] : '';
270
+        if (!empty($pay_method)) $where['a.pay_method'] = $pay_method;
271
+
272
+        // 会员级别查询
273
+        $level = !empty($post['level']) ? $post['level'] : 0;
274
+        if (!empty($level)) $where['b.level'] = $level;
275
+
276
+        // 会员级别查询
277
+        $level_id = !empty($post['level_id']) ? $post['level_id'] : 0;
278
+        if (!empty($level_id)) $where['a.level_id'] = $level_id;
279
+
280
+        // 指定订单状态导出
281
+        $status = !empty($post['status']) ? $post['status'] : 0;
282
+        if (!empty($post['status'])) $where['a.status'] = in_array($status, [2, 3]) ? ['IN', [2, 3]] : $status; 
283
+        // 如果传入的类型是0则强制查询已完成的订单
284
+        if (0 === $cause_type) $where['a.status'] = ['IN', [2, 3]];
285
+
286
+        // 根据日期导出
287
+        $start_time = $post['start_time'];
288
+        $end_time = $post['end_time'];
289
+        if (!empty($start_time) && !empty($end_time)) {
290
+            $start_time = strtotime($start_time);
291
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
292
+            $where['a.add_time'] = ['between', [$start_time, $end_time]];
293
+        } elseif (!empty($start_time) && empty($end_time)) {
294
+            $start_time = strtotime($start_time);
295
+            $where['a.add_time'] = ['>=', $start_time];
296
+        } elseif (empty($start_time) && !empty($end_time)) {
297
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
298
+            $where['a.add_time'] = ['<=', $end_time];
299
+        }
300
+
301
+        // 查询字段
302
+        $Field = 'a.order_number, a.money, b.username, a.add_time, a.status, a.update_time, a.pay_method, a.cause, b.level';
303
+        // 执行查询
304
+        $MoneyData = Db::name('users_money')
305
+            ->alias('a')
306
+            ->field($Field)
307
+            ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
308
+            ->where($where)
309
+            ->order('a.status desc, a.moneyid desc')
310
+            ->select();
311
+
312
+        // 充值状态
313
+        $pay_status_arr = config('global.pay_status_arr');
314
+        // 支付方式
315
+        $pay_method_arr = config('global.pay_method_arr');
316
+        // 处理订单导出数据
317
+        $ExcelData = [];
318
+        if (0 === $cause_type) {
319
+            // 升级订单
320
+            foreach ($MoneyData as $key => $value) {
321
+                $value['cause'] = unserialize($value['cause']);
322
+                // 拼装追加数据
323
+                $PushData = [
324
+                    // 订单信息
325
+                    'order_number' => $value['order_number']. "\t",
326
+                    'type_name'    => $value['cause']['type_name'],
327
+                    'money'        => $value['money'],
328
+                    'add_time'     => date('Y-m-d H:i:s', $value['add_time']),
329
+                    'status'       => $pay_status_arr[$value['status']],
330
+                    // 会员账号
331
+                    'username'     => $value['username'],
332
+                    // 支付信息
333
+                    'update_time'  => in_array($value['status'], [2, 3]) ? date('Y-m-d H:i:s', $value['update_time']) : '',
334
+                    'pay_method'   => in_array($value['status'], [2, 3]) ? $pay_method_arr[$value['pay_method']] : ''
335
+                ];
336
+                // 追加数据,用于导出
337
+                array_push($ExcelData, $PushData);
338
+                // 导出字段设置
339
+                $ExcelField = ['order_number', 'type_name', 'money', 'username', 'add_time', 'status', 'update_time', 'pay_method'];
340
+                // 导出标题设置
341
+                $ExcelTitle = ['订单号', '产品名称', '订单金额', '会员账号', '升级时间', '订单状态', '支付时间', '支付方式'];
342
+            }
343
+        } else {
344
+            // 充值订单
345
+            foreach ($MoneyData as $key => $value) {
346
+                // 拼装追加数据
347
+                $PushData = [
348
+                    // 订单信息
349
+                    'order_number' => $value['order_number']. "\t",
350
+                    'money'        => $value['money'],
351
+                    'add_time'     => date('Y-m-d H:i:s', $value['add_time']),
352
+                    'status'       => $pay_status_arr[$value['status']],
353
+                    // 会员账号
354
+                    'username'     => $value['username'],
355
+                    // 支付信息
356
+                    'update_time'  => in_array($value['status'], [2, 3]) ? date('Y-m-d H:i:s', $value['update_time']) : '',
357
+                    'pay_method'   => in_array($value['status'], [2, 3]) ? $pay_method_arr[$value['pay_method']] : ''
358
+                ];
359
+                // 追加数据,用于导出
360
+                array_push($ExcelData, $PushData);
361
+            }
362
+            // 导出字段设置
363
+            $ExcelField = ['order_number', 'money', 'username', 'add_time', 'status', 'update_time', 'pay_method'];
364
+            // 导出标题设置
365
+            $ExcelTitle = ['订单号', '充值金额', '会员账号', '充值时间', '订单状态', '支付时间', '支付方式'];
366
+        }
367
+        
368
+        // 返回导出所需数据及参数
369
+        $ReturnData = [
370
+            'ExcelData' => $ExcelData,
371
+            'ExcelField' => $ExcelField,
372
+            'ExcelTitle' => $ExcelTitle
373
+        ];
374
+        return $ReturnData;
375
+    }
376
+
377
+    // 查询视频订单并处理
378
+    private function GetMediaOrder($post = [])
379
+    {
380
+        // 查询条件
381
+        $where = [
382
+            'a.lang' => $this->admin_lang
383
+        ];
384
+
385
+        // 订单状态搜索
386
+        $order_status = !empty($post['order_status']) ? $post['order_status'] : 0;
387
+        if (!empty($order_status)) $where['a.order_status'] = intval($order_status) === 1 ? intval($order_status) : 0;
388
+
389
+        // 订单号或用户名搜索
390
+        $keywords = !empty($post['keywords']) ? $post['keywords'] : '';
391
+        if (!empty($keywords)) $where['a.order_code|b.username'] = ['LIKE', "%{$keywords}%"];
392
+
393
+        // 支付方式查询
394
+        $pay_name = !empty($post['pay_name']) ? $post['pay_name'] : '';
395
+        if (!empty($pay_name)) $where['a.pay_name'] = $pay_name;
396
+
397
+        // 根据日期导出
398
+        $start_time = $post['start_time'];
399
+        $end_time = $post['end_time'];
400
+        if (!empty($start_time) && !empty($end_time)) {
401
+            $start_time = strtotime($start_time);
402
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
403
+            $where['a.add_time'] = ['between', [$start_time, $end_time]];
404
+        } elseif (!empty($start_time) && empty($end_time)) {
405
+            $start_time = strtotime($start_time);
406
+            $where['a.add_time'] = ['>=', $start_time];
407
+        } elseif (empty($start_time) && !empty($end_time)) {
408
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
409
+            $where['a.add_time'] = ['<=', $end_time];
410
+        }
411
+
412
+        // 查询字段
413
+        $Field = 'a.order_code, a.order_amount, b.username, a.mobile, a.add_time, a.order_status';
414
+        // 执行查询
415
+        $MediaData = Db::name('media_order')
416
+            ->alias('a')
417
+            ->field($Field)
418
+            ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
419
+            ->where($where)
420
+            ->order('a.order_status desc, a.order_id desc')
421
+            ->select();
422
+        // 处理订单导出数据
423
+        $ExcelData = [];
424
+        foreach ($MediaData as $key => $value) {
425
+            // 拼装追加数据
426
+            $PushData = [
427
+                // 订单信息
428
+                'order_code'   => $value['order_code']. "\t",
429
+                'order_amount' => $value['order_amount'],
430
+                'add_time'     => date('Y-m-d H:i:s', $value['add_time']),
431
+                'order_status' => 1 == $value['order_status'] ? '已付款' : '未付款',
432
+                // 会员账号
433
+                'mobile'       => $value['mobile'],
434
+                'username'     => $value['username']
435
+            ];
436
+            // 追加数据,用于导出
437
+            array_push($ExcelData, $PushData);
438
+        }
439
+        // 导出字段设置
440
+        $ExcelField = ['order_code', 'order_amount', 'username', 'mobile', 'add_time', 'order_status'];
441
+        // 导出标题设置
442
+        $ExcelTitle = ['订单号', '订单金额', '会员账号', '会员手机', '下单时间', '订单状态'];
443
+
444
+        // 返回导出所需数据及参数
445
+        $ReturnData = [
446
+            'ExcelData' => $ExcelData,
447
+            'ExcelField' => $ExcelField,
448
+            'ExcelTitle' => $ExcelTitle
449
+        ];
450
+        return $ReturnData;
451
+    }
452
+
453
+    // 查询文章订单并处理
454
+    private function GetArticleOrder($post = [])
455
+    {
456
+        // 查询条件
457
+        $where = [
458
+            'a.lang' => $this->admin_lang
459
+        ];
460
+
461
+        // 订单状态搜索
462
+        $order_status = !empty($post['order_status']) ? $post['order_status'] : 0;
463
+        if (!empty($order_status)) $where['a.order_status'] = intval($order_status) === 1 ? intval($order_status) : 0;
464
+
465
+        // 订单号或用户名搜索
466
+        $keywords = !empty($post['keywords']) ? $post['keywords'] : '';
467
+        if (!empty($keywords)) $where['a.order_code|b.username'] = ['LIKE', "%{$keywords}%"];
468
+
469
+        // 支付方式查询
470
+        $pay_name = !empty($post['pay_name']) ? $post['pay_name'] : '';
471
+        if (!empty($pay_name)) $where['a.pay_name'] = $pay_name;
472
+
473
+        // 根据日期导出
474
+        $start_time = $post['start_time'];
475
+        $end_time = $post['end_time'];
476
+        if (!empty($start_time) && !empty($end_time)) {
477
+            $start_time = strtotime($start_time);
478
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
479
+            $where['a.add_time'] = ['between', [$start_time, $end_time]];
480
+        } elseif (!empty($start_time) && empty($end_time)) {
481
+            $start_time = strtotime($start_time);
482
+            $where['a.add_time'] = ['>=', $start_time];
483
+        } elseif (empty($start_time) && !empty($end_time)) {
484
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
485
+            $where['a.add_time'] = ['<=', $end_time];
486
+        }
487
+
488
+        // 查询字段
489
+        $Field = 'a.order_code, a.order_amount, b.username, a.add_time, a.order_status';
490
+        // 执行查询
491
+        $ArticleData = Db::name('article_order')
492
+            ->alias('a')
493
+            ->field($Field)
494
+            ->join('__USERS__ b', 'a.users_id = b.users_id', 'LEFT')
495
+            ->where($where)
496
+            ->order('a.order_status desc, a.order_id desc')
497
+            ->select();
498
+
499
+        // 处理订单导出数据
500
+        $ExcelData = [];
501
+        foreach ($ArticleData as $key => $value) {
502
+            // 拼装追加数据
503
+            $PushData = [
504
+                // 订单信息
505
+                'order_code'   => $value['order_code']. "\t",
506
+                'order_amount' => $value['order_amount'],
507
+                'add_time'     => date('Y-m-d H:i:s', $value['add_time']),
508
+                'order_status' => 1 == $value['order_status'] ? '已付款' : '未付款',
509
+                // 会员账号
510
+                'username'     => $value['username']
511
+            ];
512
+            // 追加数据,用于导出
513
+            array_push($ExcelData, $PushData);
514
+        }
515
+        // 导出字段设置
516
+        $ExcelField = ['order_code', 'order_amount', 'username', 'add_time', 'order_status'];
517
+        // 导出标题设置
518
+        $ExcelTitle = ['订单号', '订单金额', '会员账号', '下单时间', '订单状态'];
519
+
520
+        // 返回导出所需数据及参数
521
+        $ReturnData = [
522
+            'ExcelData' => $ExcelData,
523
+            'ExcelField' => $ExcelField,
524
+            'ExcelTitle' => $ExcelTitle
525
+        ];
526
+        return $ReturnData;
527
+    }
528
+
529
+    // 查询售后订单并处理
530
+    private function GetServiceOrder($post = [])
531
+    {
532
+        // 初始化数组和条件
533
+        $where =[];
534
+
535
+        // 订单号查询
536
+        $order_code = !empty($post['order_code']) ? trim($post['order_code']) : '';
537
+        if (!empty($order_code)) $where['a.order_code|a.product_name'] = ['LIKE', "%{$order_code}%"];
538
+
539
+        // 支付方式查询
540
+        $pay_name = !empty($post['pay_name']) ? $post['pay_name'] : '';
541
+        if (!empty($pay_name)) $where['c.pay_name'] = $pay_name;
542
+
543
+        // 订单下单终端查询
544
+        $order_terminal = !empty($post['order_terminal']) ? $post['order_terminal'] : 0;
545
+        if (!empty($order_terminal)) $where['c.order_terminal'] = $order_terminal;
546
+
547
+        // 根据日期导出
548
+        $start_time = $post['start_time'];
549
+        $end_time = $post['end_time'];
550
+        if (!empty($start_time) && !empty($end_time)) {
551
+            $start_time = strtotime($start_time);
552
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
553
+            $where['a.add_time'] = ['between', [$start_time, $end_time]];
554
+        } elseif (!empty($start_time) && empty($end_time)) {
555
+            $start_time = strtotime($start_time);
556
+            $where['a.add_time'] = ['>=', $start_time];
557
+        } elseif (empty($start_time) && !empty($end_time)) {
558
+            $end_time = strtotime("+1 day", strtotime($end_time)) - 1;
559
+            $where['a.add_time'] = ['<=', $end_time];
560
+        }
561
+
562
+        $Service = Db::name('shop_order_service')->alias('a')
563
+            ->field('a.*, b.product_price, b.num as product_num, d.username')
564
+            ->join('__SHOP_ORDER_DETAILS__ b', 'a.details_id = b.details_id', 'LEFT')
565
+            ->join('__SHOP_ORDER__ c', 'a.order_id = c.order_id', 'LEFT')
566
+            ->join('__USERS__ d', 'a.users_id = d.users_id', 'LEFT')
567
+            ->where($where)
568
+            ->order('a.service_id desc')
569
+            ->select();
570
+        // 获取订单状态
571
+        $ServiceStatus = Config::get('global.order_service_status');
572
+        // 处理订单导出数据
573
+        $ExcelData = [];
574
+        foreach ($Service as $key => $value) {
575
+            $service_type = '换货';
576
+            if (2 === intval($value['service_type'])) {
577
+                $service_type = '退货';
578
+            } else if (3 === intval($value['service_type'])) {
579
+                $service_type = '维修';
580
+            }
581
+            // 拼装追加数据
582
+            $PushData = [
583
+                // 订单信息
584
+                'order_code' => $value['order_code'] . "\t",
585
+                'refund_code' => $value['refund_code'] . "\t",
586
+                'product_name' => $value['product_name'],
587
+                'product_price' => $value['product_price'],
588
+                'product_num' => $value['product_num'],
589
+                'refund_price' => $value['refund_price'],
590
+                'service_type' => $service_type,
591
+                'status' => $ServiceStatus[$value['status']],
592
+                'add_time' => date('Y-m-d H:i:s', $value['add_time']),
593
+                // 会员账号
594
+                'username' => $value['username'],
595
+                // 收货信息
596
+                'consignee' => $value['consignee'],
597
+                'mobile' => $value['mobile'],
598
+                'address' => trim($value['address']),
599
+            ];
600
+            // 追加数据,用于导出
601
+            array_push($ExcelData, $PushData);
602
+        }
603
+
604
+        // 导出字段设置
605
+        $ExcelField = ['order_code', 'refund_code', 'product_name', 'product_price', 'product_num', 'refund_price', 'service_type', 'status', 'add_time', 'username', 'consignee', 'mobile', 'address'];
606
+        // 导出标题设置
607
+        $ExcelTitle = ['订单号', '服务单号', '商品名称', '商品价格', '商品数量', '退还金额', '售后类型', '处理状态', '售后时间', '会员账号', '收货人', '联系电话', '收货地址'];
608
+
609
+        // 返回导出所需数据及参数
610
+        $ReturnData = [
611
+            'ExcelData' => $ExcelData,
612
+            'ExcelField' => $ExcelField,
613
+            'ExcelTitle' => $ExcelTitle
614
+        ];
615
+        return $ReturnData;
616
+    }
617
+
618
+    // 执行导出下载
619
+    private function PerformExport($ExcelData = [], $ExcelField = [], $ExcelTitle = [], $export_type = [])
620
+    {
621
+        // 引入SDK
622
+        vendor("PHPExcel.Classes.PHPExcel");
623
+
624
+        // Excel表格坐标
625
+        $cell_arr = ['A','B','C','D','E','F','G','H','I','J','K','L','M', 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
626
+
627
+        // 执行导出
628
+        $objPHPExcel = new \PHPExcel();  
629
+        $objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')->setSize(12);
630
+
631
+        // 设置表格标题栏长度
632
+        $objActSheet = $objPHPExcel->getActiveSheet();
633
+        if (1 == $export_type) {// 商城订单
634
+            $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(22);
635
+            $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
636
+            $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(8);
637
+            $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(8);
638
+            $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(18);
639
+            $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(8);
640
+            $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(18);
641
+            $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(10);
642
+            $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(8);
643
+            $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(22);
644
+            $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8);
645
+            $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(8);
646
+            $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(13);
647
+            $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(40);
648
+            // 设置导出表格名称
649
+            $FileName = 'shop-order-'.date("YmdHis");
650
+
651
+        } else if (2 == $export_type) {// 充值订单
652
+            // 设置导出表格标题宽度
653
+            $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(22);
654
+            $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(10);
655
+            $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(10);
656
+            $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(18);
657
+            $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(10);
658
+            $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(18);
659
+            $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(10);
660
+            // 设置导出表格名称
661
+            $FileName = 'money-order-'.date("YmdHis");
662
+
663
+        } else if (3 == $export_type) {// 充值订单
664
+            // 设置导出表格标题宽度
665
+            $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(22);
666
+            $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(20);
667
+            $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(10);
668
+            $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10);
669
+            $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(18);
670
+            $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(10);
671
+            $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(18);
672
+            $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(10);
673
+            // 设置导出表格名称
674
+            $FileName = 'upgrade-order-'.date("YmdHis");
675
+
676
+        } else if (4 == $export_type) {// 视频订单
677
+            // 设置导出表格标题宽度
678
+            $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(18);
679
+            $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(10);
680
+            $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(10);
681
+            $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(13);
682
+            $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(18);
683
+            $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(10);
684
+            // 设置导出表格名称
685
+            $FileName = 'media-order-'.date("YmdHis");
686
+
687
+        } else if (5 == $export_type) {// 文章订单
688
+            // 设置导出表格标题宽度
689
+            $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(18);
690
+            $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(10);
691
+            $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(10);
692
+            $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(13);
693
+            $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(18);
694
+            // 设置导出表格名称
695
+            $FileName = 'article-order-'.date("YmdHis");
696
+
697
+        } else if (6 == $export_type) {// 售后订单
698
+            $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(22);
699
+            $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(15);
700
+            $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(22);
701
+            $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(8);
702
+            $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(8);
703
+            $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(8);
704
+            $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(8);
705
+            $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(12);
706
+            $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(18);
707
+            $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(8);
708
+            $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8);
709
+            $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(13);
710
+            $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(40);
711
+            // 设置导出表格名称
712
+            $FileName = 'service-order-'.date("YmdHis");
713
+
714
+        }
715
+
716
+        // 循环设置表格标题栏数据
717
+        $startRow = 1;
718
+        if(!empty($ExcelTitle) || count($ExcelTitle) > 0) {
719
+            foreach($ExcelTitle as $k => $v) {
720
+                $objActSheet->setCellValue($cell_arr[$k] . $startRow, $v);
721
+            }
722
+            $startRow = 2;
723
+        }
724
+
725
+        // 循环设置表格字段内容数据
726
+        foreach($ExcelData as $v) {
727
+            $columnField = 'A';
728
+            foreach($ExcelField as $key => $value) {
729
+                $objActSheet->setCellValue($cell_arr[$key] . $startRow, $v[$value]);
730
+                if (1 == $export_type) {// 商城订单
731
+                    $product_name_arr = explode(PHP_EOL, $v['product_name']);
732
+                    $product_name_num = count($product_name_arr);
733
+                    $height = ($product_name_num * 15) + 5;
734
+                    $objActSheet->getRowDimension($startRow)->setRowHeight($height);// 设置行高
735
+                    $objActSheet->getStyle($columnField.($startRow))->getAlignment()->setWrapText(true);//设置自动换行
736
+                    $objActSheet->getStyle($columnField. $startRow)->getAlignment()->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);//垂直居中
737
+                    $columnField++;
738
+                }
739
+            }
740
+            $startRow++;
741
+        }
742
+        
743
+        $objPHPExcel->setActiveSheetIndex(0);
744
+        header('Content-Type: application/vnd.ms-excel');
745
+        header('Content-Disposition: attachment;filename="' . $FileName . '.xlsx"');
746
+        header('Cache-Control: max-age=0');
747
+        header('Cache-Control: max-age=1');
748
+        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
749
+        header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
750
+        header('Cache-Control: cache, must-revalidate');
751
+        header('Pragma: public');
752
+        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
753
+
754
+        // 文件目录
755
+        $ExcelPath = UPLOAD_PATH . 'excel/';
756
+        // 保存前清空删除原先的excel
757
+        delFile(UPLOAD_PATH . 'excel/', true);
758
+        // 创建文件夹
759
+        @mkdir($ExcelPath, 0777, true);
760
+        // excel文件路径
761
+        $filePath = $ExcelPath . $FileName . '.xlsx';
762
+        // 保存excel文件
763
+        $objWriter->save($filePath);
764
+        // 返回excel文件路径到AJAX下载
765
+        return request()->domain() . ROOT_DIR . '/' . $filePath;
766
+    }
767
+}

+ 484
- 0
application/admin/controller/Other.php View File

@@ -0,0 +1,484 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+
19
+class Other extends Base
20
+{
21
+    /*
22
+     * 初始化操作
23
+     */
24
+    public function _initialize() 
25
+    {
26
+        parent::_initialize();
27
+        // 判断是否有广告位置
28
+        if (strtolower(ACTION_NAME) != 'index') {
29
+            $count = Db::name('ad_position')->count('id');
30
+            if (empty($count)) {
31
+                $this->success('缺少广告位置,正在前往中……', url('AdPosition/add'), '', 3);
32
+                exit;
33
+            }
34
+        }
35
+    }
36
+
37
+    public function index()
38
+    {
39
+        $list = array();
40
+        $get = input('get.');
41
+        $pid = input('param.pid/d', 0);
42
+        $keywords = input('keywords/s');
43
+        $condition = array();
44
+        // 应用搜索条件
45
+        foreach (['keywords', 'pid'] as $key) {
46
+            if (isset($get[$key]) && $get[$key] !== '') {
47
+                if ($key == 'keywords') {
48
+                    $condition['a.title'] = array('LIKE', "%{$get[$key]}%");
49
+                } else {
50
+                    $tmp_key = 'a.'.$key;
51
+                    $condition[$tmp_key] = array('eq', $get[$key]);
52
+                }
53
+            }
54
+        }
55
+
56
+        // 多语言
57
+        $condition['a.lang'] = array('eq', $this->admin_lang);
58
+
59
+        $adM =  Db::name('ad');
60
+        $count = $adM->alias('a')->where($condition)->count();// 查询满足要求的总记录数
61
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
62
+        $list = $adM->alias('a')->where($condition)->order('id desc')->limit($Page->firstRow.','.$Page->listRows)->select();
63
+        /*支持子目录*/
64
+        foreach ($list as $key => $val) {
65
+            $val['litpic'] = handle_subdir_pic($val['litpic']);
66
+            $list[$key] = $val;
67
+        }
68
+        /*--end*/
69
+
70
+        $show = $Page->show();// 分页显示输出
71
+        $this->assign('page',$show);// 赋值分页输出
72
+        $this->assign('list',$list);// 赋值数据集
73
+        $this->assign('pager',$Page);// 赋值分页对象
74
+
75
+        $ad_position = model('AdPosition')->getAll('*','id');
76
+        $this->assign('ad_position',$ad_position);
77
+
78
+        $this->assign('pid',$pid);// 赋值分页对象
79
+        return $this->fetch();
80
+    }
81
+    
82
+    /**
83
+     * 新增
84
+     */
85
+    public function add()
86
+    {
87
+        $this->language_access(); // 多语言功能操作权限
88
+
89
+        if (IS_POST) {
90
+            $post = input('post.');
91
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
92
+            $litpic = '';
93
+            if ($is_remote == 1) {
94
+                $litpic = $post['litpic_remote'];
95
+            } else {
96
+                $litpic = $post['litpic_local'];
97
+            }
98
+            $newData = array(
99
+                'litpic'            => $litpic,
100
+                'admin_id'  => session('admin_id'),
101
+                'lang'  => $this->admin_lang,
102
+                'sort_order'    => 100,
103
+                'add_time'           => getTime(),
104
+                'update_time'   => getTime(),
105
+            );
106
+            $data = array_merge($post, $newData);
107
+            $insertId = Db::name('ad')->insertGetId($data);
108
+
109
+            if ($insertId) {
110
+
111
+                /*同步广告位置ID到多语言的模板变量里*/
112
+                $this->syn_add_language_attribute($insertId);
113
+                /*--end*/
114
+
115
+                \think\Cache::clear('ad');
116
+                adminLog('新增广告:'.$post['title']);
117
+                $this->success("操作成功", url('Other/index'));
118
+            } else {
119
+                $this->error("操作失败");
120
+            }
121
+            exit;
122
+        }
123
+
124
+        $pid = input('param.pid/d', 0);
125
+        $this->assign('pid', $pid);
126
+
127
+        $ad_position = model('AdPosition')->getAll('*', 'id');
128
+        $this->assign('ad_position', $ad_position);
129
+
130
+        $ad_media_type = config('global.ad_media_type');
131
+        $this->assign('ad_media_type', $ad_media_type);
132
+
133
+        return $this->fetch();
134
+    }
135
+
136
+    
137
+    /**
138
+     * 编辑
139
+     */
140
+    public function edit()
141
+    {
142
+        if (IS_POST) {
143
+            $post = input('post.');
144
+            if(!empty($post['id'])){
145
+                $post['id'] = intval($post['id']);
146
+                $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
147
+                $litpic = '';
148
+                if ($is_remote == 1) {
149
+                    $litpic = $post['litpic_remote'];
150
+                } else {
151
+                    $litpic = $post['litpic_local'];
152
+                }
153
+                $newData = array(
154
+                    'litpic'            => $litpic,
155
+                    'update_time'       => getTime(),
156
+                );
157
+                $data = array_merge($post, $newData);
158
+                $r = Db::name('ad')->where([
159
+                        'id'    => $post['id'],
160
+                    ])
161
+                    ->cache(true,null,'ad')
162
+                    ->update($data);
163
+            }
164
+            if ($r) {
165
+                adminLog('编辑广告');
166
+                $this->success("操作成功", url('Other/index'));
167
+            } else {
168
+                $this->error("操作失败");
169
+            }
170
+        }
171
+
172
+        $assign_data = array();
173
+
174
+        $id = input('id/d');
175
+        $field = Db::name('ad')->where([
176
+                'id'    => $id,
177
+            ])->find();
178
+        if (empty($field)) {
179
+            $this->error('广告不存在,请联系管理员!');
180
+            exit;
181
+        }
182
+        if (is_http_url($field['litpic'])) {
183
+            $field['is_remote'] = 1;
184
+            $field['litpic_remote'] = handle_subdir_pic($field['litpic']);
185
+        } else {
186
+            $field['is_remote'] = 0;
187
+            $field['litpic_local'] = handle_subdir_pic($field['litpic']);
188
+        }
189
+        
190
+        /*支持子目录*/
191
+        $field['intro'] = handle_subdir_pic($field['intro'], 'html');
192
+        /*--end*/
193
+
194
+        $assign_data['field'] = $field;
195
+        $assign_data['ad_position'] = model('AdPosition')->getAll('*', 'id');
196
+
197
+        $assign_data['ad_media_type'] = config('global.ad_media_type');
198
+
199
+        $this->assign($assign_data);
200
+        return $this->fetch();
201
+    }
202
+    
203
+    /**
204
+     * 删除
205
+     */
206
+    public function del()
207
+    {
208
+        $this->language_access(); // 多语言功能操作权限
209
+
210
+        $id_arr = input('del_id/a');
211
+        $id_arr = eyIntval($id_arr);
212
+        if(!empty($id_arr)){
213
+
214
+            /*多语言*/
215
+            $attr_name_arr = [];
216
+            foreach ($id_arr as $key => $val) {
217
+                $attr_name_arr[] = 'ad'.$val;
218
+            }
219
+            if (is_language()) {
220
+                $new_id_arr = Db::name('language_attr')->where([
221
+                        'attr_name' => ['IN', $attr_name_arr],
222
+                        'attr_group'    => 'ad',
223
+                    ])->column('attr_value');
224
+                !empty($new_id_arr) && $id_arr = $new_id_arr;
225
+            }
226
+            /*--end*/
227
+            $r = Db::name('ad')->where([
228
+                    'id'    => ['IN', $id_arr],
229
+                ])
230
+                ->cache(true,null,'ad')
231
+                ->delete();
232
+            if ($r) {
233
+
234
+                /*多语言*/
235
+                if (!empty($attr_name_arr)) {
236
+                    Db::name('language_attr')->where([
237
+                            'attr_name' => ['IN', $attr_name_arr],
238
+                            'attr_group'    => 'ad',
239
+                        ])->delete();
240
+                    Db::name('language_attribute')->where([
241
+                            'attr_name' => ['IN', $attr_name_arr],
242
+                            'attr_group'    => 'ad',
243
+                        ])->delete();
244
+                }
245
+                /*--end*/
246
+
247
+                adminLog('删除广告-id:'.implode(',', $id_arr));
248
+                $this->success('删除成功');
249
+            } else {
250
+                $this->error('删除失败');
251
+            }
252
+        }else{
253
+            $this->error('参数有误');
254
+        }
255
+    }
256
+
257
+    /**
258
+     * ui美化新增
259
+     */
260
+    public function ui_add()
261
+    {
262
+        $this->language_access(); // 多语言功能操作权限
263
+
264
+        if (IS_POST) {
265
+            $post = input('post.');
266
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
267
+            $litpic = '';
268
+            if ($is_remote == 1) {
269
+                $litpic = $post['litpic_remote'];
270
+            } else {
271
+                $litpic = $post['litpic_local'];
272
+            }
273
+            $newData = array(
274
+                'media_type'    => 1,
275
+                'litpic'            => $litpic,
276
+                'lang'  => get_current_lang(),
277
+                'add_time'       => getTime(),
278
+                'update_time'       => getTime(),
279
+            );
280
+            $data = array_merge($post, $newData);
281
+            $insertId = Db::name('ad')->insertGetId($data);
282
+            if ($insertId) {
283
+
284
+                /*同步广告位置ID到多语言的模板变量里*/
285
+                $this->syn_add_language_attribute($insertId);
286
+                /*--end*/
287
+
288
+                \think\Cache::clear('ad');
289
+                adminLog('新增广告:'.$post['title']);
290
+                $this->success('操作成功');
291
+            } else {
292
+                $this->error('操作失败');
293
+            }
294
+        }
295
+
296
+        $edit_id = input('param.edit_id/d', 0);
297
+        $pid = input('param.pid/d', 0);
298
+        /*多语言*/
299
+        $new_pid = model('LanguageAttr')->getBindValue($pid, 'ad_position');
300
+        !empty($new_pid) && $pid = $new_pid;
301
+        /*--end*/
302
+        $assign_data = array();
303
+        $assign_data['ad_position'] = model('AdPosition')->getInfo($pid);
304
+        $assign_data['edit_id'] = $edit_id;
305
+
306
+        $this->assign($assign_data);
307
+        return $this->fetch();
308
+    }
309
+
310
+    /**
311
+     * ui美化编辑
312
+     */
313
+    public function ui_edit()
314
+    {
315
+        if (IS_POST) {
316
+            $post = input('post.');
317
+            if(!empty($post['id'])){
318
+                $post['id'] = intval($post['id']);
319
+                $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
320
+                $litpic = '';
321
+                if ($is_remote == 1) {
322
+                    $litpic = $post['litpic_remote'];
323
+                } else {
324
+                    $litpic = $post['litpic_local'];
325
+                }
326
+                $newData = array(
327
+                    'litpic'            => $litpic,
328
+                    'update_time'       => getTime(),
329
+                );
330
+                $data = array_merge($post, $newData);
331
+                $r = Db::name('ad')->where([
332
+                        'id'    => $post['id'],
333
+                    ])
334
+                    ->cache(true,null,'ad')
335
+                    ->update($data);
336
+                if ($r) {
337
+                    adminLog('编辑广告:'.$post['title']);
338
+                    $this->success('操作成功');
339
+                }
340
+            }
341
+            $this->error('操作失败');
342
+        }
343
+
344
+        $assign_data = array();
345
+
346
+        $id = input('id/d');
347
+        $field = Db::name('ad')->where([
348
+                'id'    => $id,
349
+            ])->find();
350
+        if (empty($field)) {
351
+            $this->error('广告不存在,请联系管理员!');
352
+            exit;
353
+        }
354
+        if (is_http_url($field['litpic'])) {
355
+            $field['is_remote'] = 1;
356
+            $field['litpic_remote'] = $field['litpic'];
357
+        } else {
358
+            $field['is_remote'] = 0;
359
+            $field['litpic_local'] = $field['litpic'];
360
+        }
361
+        $assign_data['field'] = $field;
362
+        $assign_data['ad_position'] = model('AdPosition')->getInfo($field['pid']);
363
+
364
+        $this->assign($assign_data);
365
+        return $this->fetch();
366
+    }
367
+    
368
+    /**
369
+     * 删除
370
+     */
371
+    public function ui_del()
372
+    {
373
+        $this->language_access(); // 多语言功能操作权限
374
+        
375
+        $id_arr = input('del_id/a');
376
+        $id_arr = eyIntval($id_arr);
377
+        if(!empty($id_arr)){
378
+
379
+            /*多语言*/
380
+            $attr_name_arr = [];
381
+            foreach ($id_arr as $key => $val) {
382
+                $attr_name_arr[] = 'ad'.$val;
383
+            }
384
+            if (is_language()) {
385
+                $new_id_arr = Db::name('language_attr')->where([
386
+                        'attr_name' => ['IN', $attr_name_arr],
387
+                        'attr_group'    => 'ad',
388
+                    ])->column('attr_value');
389
+                !empty($new_id_arr) && $id_arr = $new_id_arr;
390
+            }
391
+            /*--end*/
392
+
393
+            $r = Db::name('ad')->where([
394
+                    'id'    => ['IN', $id_arr],
395
+                ])
396
+                ->cache(true,null,'ad')
397
+                ->delete();
398
+            if ($r) {
399
+
400
+                /*多语言*/
401
+                if (!empty($attr_name_arr)) {
402
+                    Db::name('language_attr')->where([
403
+                            'attr_name' => ['IN', $attr_name_arr],
404
+                            'attr_group'    => 'ad',
405
+                        ])->delete();
406
+                    Db::name('language_attribute')->where([
407
+                            'attr_name' => ['IN', $attr_name_arr],
408
+                            'attr_group'    => 'ad',
409
+                        ])->delete();
410
+                }
411
+                /*--end*/
412
+
413
+                adminLog('删除广告-id:'.implode(',', $id_arr));
414
+                $this->success('删除成功');
415
+            } else {
416
+                $this->error('删除失败');
417
+            }
418
+        }else{
419
+            $this->error('参数有误');
420
+        }
421
+    }
422
+
423
+    /**
424
+     * 同步新增广告ID到多语言的模板变量里
425
+     */
426
+    private function syn_add_language_attribute($ad_id)
427
+    {
428
+        /*单语言情况下不执行多语言代码*/
429
+        if (!is_language()) {
430
+            return true;
431
+        }
432
+        /*--end*/
433
+
434
+        $attr_group = 'ad';
435
+        $admin_lang = $this->admin_lang;
436
+        $main_lang = get_main_lang();
437
+        $languageRow = Db::name('language')->field('mark')->order('id asc')->select();
438
+        if (!empty($languageRow) && $admin_lang == $main_lang) { // 当前语言是主体语言,即语言列表最早新增的语言
439
+            $ad_db = Db::name('ad');
440
+            $result = $ad_db->find($ad_id);
441
+            $attr_name = 'ad'.$ad_id;
442
+            $r = Db::name('language_attribute')->save([
443
+                'attr_title'    => $result['title'],
444
+                'attr_name'     => $attr_name,
445
+                'attr_group'    => $attr_group,
446
+                'add_time'      => getTime(),
447
+                'update_time'   => getTime(),
448
+            ]);
449
+            if (false !== $r) {
450
+                $data = [];
451
+                foreach ($languageRow as $key => $val) {
452
+                    /*同步新广告到其他语言广告列表*/
453
+                    if ($val['mark'] != $admin_lang) {
454
+                        $addsaveData = $result;
455
+                        $addsaveData['lang'] = $val['mark'];
456
+                        $newPid = Db::name('language_attr')->where([
457
+                                'attr_name' => 'adp'.$result['pid'],
458
+                                'attr_group'    => 'ad_position',
459
+                                'lang'  => $val['mark'],
460
+                            ])->getField('attr_value');
461
+                        $addsaveData['pid'] = $newPid;
462
+                        unset($addsaveData['id']);
463
+                        $ad_id = $ad_db->insertGetId($addsaveData);
464
+                    }
465
+                    /*--end*/
466
+                    
467
+                    /*所有语言绑定在主语言的ID容器里*/
468
+                    $data[] = [
469
+                        'attr_name' => $attr_name,
470
+                        'attr_value'    => $ad_id,
471
+                        'lang'  => $val['mark'],
472
+                        'attr_group'    => $attr_group,
473
+                        'add_time'      => getTime(),
474
+                        'update_time'   => getTime(),
475
+                    ];
476
+                    /*--end*/
477
+                }
478
+                if (!empty($data)) {
479
+                    model('LanguageAttr')->saveAll($data);
480
+                }
481
+            }
482
+        }
483
+    }
484
+}

+ 222
- 0
application/admin/controller/PayApi.php View File

@@ -0,0 +1,222 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 陈风任 <491085389@qq.com>
11
+ * Date: 2020-05-22
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Config;
19
+
20
+class PayApi extends Base {
21
+
22
+    private $UsersConfigData = [];
23
+
24
+    /**
25
+     * 构造方法
26
+     */
27
+    public function __construct(){
28
+        parent::__construct();
29
+        $this->language_access(); // 多语言功能操作权限
30
+        $this->pay_api_config_db = Db::name('pay_api_config');
31
+
32
+        // 会员中心配置信息
33
+        $this->UsersConfigData = getUsersConfigData('all');
34
+        $this->assign('userConfig', $this->UsersConfigData);
35
+    }
36
+
37
+    /**
38
+     * 支付接口首页
39
+     */
40
+    public function pay_api_index()
41
+    {
42
+        $list = $this->pay_api_config_db->where('status', 1)->order('pay_id asc')->select();
43
+        foreach ($list as $key => $val) {
44
+            if (1 == $val['system_built']) {
45
+                $val['litpic'] = $this->root_dir . "/public/static/admin/images/{$val['pay_mark']}.png";
46
+            } else {
47
+                $val['litpic'] = $this->root_dir . "/weapp/{$val['pay_mark']}/logo.png";
48
+            }
49
+            $list[$key] = $val;
50
+        }
51
+        $this->assign('list', $list);
52
+        return $this->fetch('pay_api_index');
53
+    }
54
+
55
+    /**
56
+     * 打开支付接口配置
57
+     */
58
+    public function open_pay_api_config()
59
+    {
60
+        $pay_id = input('get.pay_id') ? input('get.pay_id') : 0;
61
+        $Config = $this->pay_api_config_db->where('pay_id', $pay_id)->find();
62
+
63
+        if (!empty($Config) && 1 == $Config['pay_id'] && 'wechat' == $Config['pay_mark']) {
64
+            // 系统内置的微信支付
65
+            $TemplateHtml = $this->WeChatPayTemplate($Config);
66
+        } else if (!empty($Config) && 2 == $Config['pay_id'] && 'alipay' == $Config['pay_mark']) {
67
+            // 系统内置的支付宝支付
68
+            $TemplateHtml = $this->AliPayPayTemplate($Config);
69
+        } else if (!empty($Config) && !empty($Config['pay_mark']) && 0 == $Config['system_built']) {
70
+            // 第三方插件
71
+            $ControllerName  = "\weapp\\" . $Config['pay_mark']."\controller\\" . $Config['pay_mark'];
72
+            $UnifyController = new $ControllerName;
73
+            $TemplateHtml = $UnifyController->UnifyAction($Config);
74
+        }
75
+
76
+        return $this->display($TemplateHtml);
77
+    }
78
+
79
+    /**
80
+     * 保存支付接口配置
81
+     */
82
+    public function save_pay_api_config()
83
+    {
84
+        if (IS_AJAX_POST) {
85
+            $post = input('post.');
86
+
87
+            $pay_id = !empty($post['pay_id']) ? $post['pay_id'] : 0;
88
+            $Config = $this->pay_api_config_db->where('pay_id', $pay_id)->find();
89
+            if (empty($Config)) $this->error('数据有误,请刷新重试');
90
+
91
+            if (1 == $Config['pay_id'] && 'wechat' == $Config['pay_mark']) {
92
+                // 系统内置的微信支付
93
+                $this->WeChatPayConfig($post);
94
+            } else if (2 == $Config['pay_id'] && 'alipay' == $Config['pay_mark']) {
95
+                // 系统内置的支付宝支付
96
+                $this->AliPayPayConfig($post);
97
+            } else if (!empty($Config) && !empty($Config['pay_mark']) && 0 == $Config['system_built']) {
98
+                // 第三方插件
99
+                $ControllerName  = "\weapp\\" . $Config['pay_mark']."\controller\\" . $Config['pay_mark'];
100
+                $UnifyController = new $ControllerName;
101
+                $UnifyController->UnifySaveConfigAction($post);
102
+            }
103
+        }
104
+    }
105
+
106
+    /* 微信逻辑 */
107
+    public function WeChatPayTemplate($Config = [])
108
+    {
109
+        $pay_info = !empty($Config['pay_info']) ? unserialize($Config['pay_info']) : [];
110
+        $Config['pay_terminal'] = !empty($Config['pay_terminal']) ? unserialize($Config['pay_terminal']) : [];
111
+        $this->assign('Config', $Config);
112
+        $this->assign('pay_info', $pay_info);
113
+        return $this->fetch('wechat_template');
114
+    }
115
+
116
+    // 保存微信配置
117
+    public function WeChatPayConfig($post = [])
118
+    {
119
+        if (empty($post['pay_info']['is_open_wechat'])) {
120
+            // 配置信息不允许为空
121
+            if (empty($post['pay_info']['appid'])) $this->error('请填写微信AppId');
122
+            if (empty($post['pay_info']['mchid'])) $this->error('请填写微信商户号');
123
+            if (empty($post['pay_info']['key']))   $this->error('请填写微信KEY值');
124
+            
125
+            // 验证微信配置是否正确,不正确则返回提示
126
+            $Result = model('PayApi')->VerifyWeChatConfig($post['pay_info']);
127
+            if (!empty($Result['return_code']) && $Result['return_code'] == 'FAIL') $this->error($Result['return_msg']);
128
+        }
129
+
130
+        // 保存配置
131
+        $SynData['pay_info'] = serialize($post['pay_info']);
132
+        // $SynData['pay_terminal'] = serialize($post['pay_terminal']);
133
+        $SynData['update_time'] = getTime();
134
+
135
+        // 保存条件
136
+        $where = [
137
+            'pay_id' => $post['pay_id'],
138
+            'pay_mark' => 'wechat',
139
+            'system_built' => 1
140
+        ];
141
+        $ResultID = $this->pay_api_config_db->where($where)->update($SynData);
142
+
143
+        // 返回结果
144
+        if (!empty($ResultID)) {
145
+            $this->success('保存成功');
146
+        } else {
147
+            $this->error('数据错误');
148
+        }
149
+    }
150
+    /* END */
151
+
152
+    /* 支付宝逻辑 */
153
+    public function AliPayPayTemplate($Config = [])
154
+    {
155
+        $pay_info = !empty($Config['pay_info']) ? unserialize($Config['pay_info']) : [];
156
+        $Config['pay_terminal'] = !empty($Config['pay_terminal']) ? unserialize($Config['pay_terminal']) : [];
157
+        $this->assign('Config', $Config);
158
+        $this->assign('pay_info', $pay_info);
159
+        // PHP5.5.0或更高版本,可使用新版支付方式,兼容旧版支付方式
160
+        $php_version = 0;
161
+        if (version_compare(PHP_VERSION, '5.5.0', '<')) {
162
+            // PHP5.4.0或更低版本,可使用旧版支付方式
163
+            $php_version = 1;
164
+        }
165
+        $this->assign('php_version', $php_version);
166
+        return $this->fetch('alipay_template');
167
+    }
168
+
169
+    // 保存支付宝支付配置
170
+    public function AliPayPayConfig($post = [])
171
+    {
172
+        $php_version = $post['pay_info']['version'];
173
+        if (0 == $php_version) {
174
+            if (empty($post['pay_info']['is_open_alipay'])) {
175
+                // 配置信息不允许为空
176
+                if (empty($post['pay_terminal']['computer']) && empty($post['pay_terminal']['computer'])) $this->error('请勾选支付终端');
177
+                if (empty($post['pay_info']['app_id'])) $this->error('请填写支付宝APPID');
178
+                if (empty($post['pay_info']['merchant_private_key'])) $this->error('请填写商户私钥');
179
+                if (empty($post['pay_info']['alipay_public_key'])) $this->error('请填写支付宝公钥');
180
+
181
+                // 验证支付宝配置是否正确,不正确则返回提示
182
+                $Result = model('PayApi')->VerifyAliPayConfig($post['pay_info']);
183
+                if ('ok' != $Result) {
184
+                    empty($Result) && $Result = '配置信息不正确,请重新获取';
185
+                    $this->error($Result);
186
+                }
187
+            }
188
+
189
+            // 处理数据中的空格和换行
190
+            $post['pay_info']['app_id'] = preg_replace('/\r|\n/', '', $post['pay_info']['app_id']);
191
+            $post['pay_info']['alipay_public_key'] = preg_replace('/\r|\n/', '', $post['pay_info']['alipay_public_key']);
192
+            $post['pay_info']['merchant_private_key'] = preg_replace('/\r|\n/', '', $post['pay_info']['merchant_private_key']);
193
+
194
+        } else if (1 == $php_version) {
195
+            if (empty($post['pay_info']['is_open_alipay'])) {
196
+                // 配置信息不允许为空
197
+                if (empty($post['pay_info']['account'])) $this->error('请填写支付宝账号');
198
+                if (empty($post['pay_info']['code'])) $this->error('请填写安全校验码');
199
+                if (empty($post['pay_info']['id'])) $this->error('请填写合作者身份ID');
200
+            }
201
+        }
202
+
203
+        // 保存配置
204
+        $SynData['pay_info'] = serialize($post['pay_info']);
205
+        $SynData['pay_terminal'] = serialize($post['pay_terminal']);
206
+        $SynData['update_time'] = getTime();
207
+        $where = [
208
+            'pay_id' => $post['pay_id'],
209
+            'pay_mark' => 'alipay',
210
+            'system_built' => 1
211
+        ];
212
+        $ResultID = $this->pay_api_config_db->where($where)->update($SynData);
213
+
214
+        // 返回结果
215
+        if (!empty($ResultID)) {
216
+            $this->success('保存成功');
217
+        } else {
218
+            $this->error('数据错误');
219
+        }
220
+    }
221
+    /* END */
222
+}

+ 1500
- 0
application/admin/controller/Product.php
File diff suppressed because it is too large
View File


+ 1246
- 0
application/admin/controller/RecycleBin.php
File diff suppressed because it is too large
View File


+ 40
- 0
application/admin/controller/Region.php View File

@@ -0,0 +1,40 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+
18
+class Region extends Base
19
+{
20
+    /**
21
+    * 获取子类列表
22
+    */  
23
+    public function ajax_get_region($pid = 0, $level = 2, $region_id = '', $text = '--请选择--'){
24
+        $data = model('Region')->getList($pid,'*','',$level);
25
+        $html = "<option value=''>".urldecode($text)."</option>";
26
+        foreach($data as $key=>$val){
27
+            if ($val['id'] == $region_id) {
28
+                unset($data[$key]);
29
+                continue;
30
+            }
31
+            $html.="<option value='".$val['id']."'>".$val['name']."</option>";
32
+        }
33
+        $isempty = 0;
34
+        if (empty($data)){
35
+            $isempty = 1;
36
+        }
37
+        $this->success($html,'',['isempty'=>$isempty]);
38
+
39
+    }
40
+}

+ 352
- 0
application/admin/controller/Search.php View File

@@ -0,0 +1,352 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class Search extends Base
21
+{
22
+    private $searchword_db;
23
+
24
+    public function _initialize() {
25
+        parent::_initialize();
26
+        $this->searchword_db = Db::name('search_word');
27
+    }
28
+
29
+    /**
30
+     * 搜索主页
31
+     */
32
+    public function index()
33
+    {
34
+        $list = array();
35
+        $param = input('param.');
36
+        $keywords = input('keywords/s');
37
+        $keywords = trim($keywords);
38
+        $condition = [];
39
+
40
+        foreach (['keywords'] as $key) {
41
+            if (isset($param[$key]) && $param[$key] !== '') {
42
+                if ($key == 'keywords') {
43
+                    $condition['word'] = array('LIKE', "%{$keywords}%");
44
+                } else {
45
+                    $condition[''.$key] = array('eq', trim($param[$key]));
46
+                }
47
+            }
48
+        }
49
+
50
+        $condition['lang'] = array('eq', $this->admin_lang);
51
+
52
+        // 自定义排序
53
+        $orderby = input('param.orderby/s');
54
+        $orderway = input('param.orderway/s');
55
+        if (!empty($orderby) && !empty($orderway)) {
56
+            $orderby = "{$orderby} {$orderway}, id desc";
57
+        } else {
58
+            $orderby = "is_hot desc, id desc";
59
+        }
60
+
61
+        $count = $this->searchword_db->where($condition)->count('id');
62
+        $Page = $pager = new Page($count, config('paginate.list_rows'));
63
+        $list = $this->searchword_db->where($condition)->order($orderby)->limit($Page->firstRow.','.$Page->listRows)->select();
64
+
65
+        $show = $Page->show();
66
+        $this->assign('page',$show);
67
+        $this->assign('list',$list);
68
+        $this->assign('pager',$pager);
69
+        return $this->fetch();
70
+    }
71
+
72
+    public function edit()
73
+    {
74
+        if (IS_AJAX_POST){
75
+            $param = input('param.');
76
+            if (empty($param['id'])){
77
+                $this->error('缺少id');
78
+            }
79
+            $update[$param['field']] = $param['value'];
80
+            $where['lang'] = array('eq', $this->admin_lang);
81
+            $where['id'] = $param['id'];
82
+            $r = $this->searchword_db->where($where)->update($update);
83
+            if (false !== $r){
84
+                $this->success('操作成功');
85
+            }
86
+        }
87
+        $this->error('操作失败');
88
+    }
89
+
90
+    public function del()
91
+    {
92
+        if (IS_POST) {
93
+            $id_arr = input('del_id/a');
94
+            $id_arr = eyIntval($id_arr);
95
+            if(!empty($id_arr)){
96
+                $result = $this->searchword_db->field('word')
97
+                    ->where([
98
+                        'id'    => ['IN', $id_arr],
99
+                        'lang'  => $this->admin_lang,
100
+                    ])->select();
101
+                $title_list = get_arr_column($result, 'word');
102
+
103
+                $r = $this->searchword_db->where([
104
+                        'id'    => ['IN', $id_arr],
105
+                        'lang'  => $this->admin_lang,
106
+                    ])
107
+                    ->cache(true, null, "search_word")
108
+                    ->delete();
109
+                if($r !== false){
110
+                    adminLog('删除搜索关键词:'.implode(',', $title_list));
111
+                    $this->success('删除成功');
112
+                }
113
+            }
114
+        }
115
+        $this->error('删除失败');
116
+    }
117
+
118
+    public function conf()
119
+    {
120
+        if (IS_POST) {
121
+            $param = input('param.');
122
+            $param['search_tabu_words'] = htmlspecialchars_decode($param['search_tabu_words']);
123
+            $search_tabu_words = explode(PHP_EOL, $param['search_tabu_words']);
124
+            foreach ($search_tabu_words as $key => $val) {
125
+                $val = trim($val);
126
+                if (!empty($val)) {
127
+                    $search_tabu_words[$key] = $val;
128
+                } else {
129
+                    unset($search_tabu_words[$key]);
130
+                }
131
+            }
132
+            $search_tabu_words = implode(PHP_EOL, $search_tabu_words);
133
+
134
+            $data = [
135
+                'search_model'=>$param['search_model'],
136
+                'search_second'=>intval($param['search_second']),
137
+                'search_maxnum'=>intval($param['search_maxnum']),
138
+                'search_locking'=>intval($param['search_locking']),
139
+                'title_word_model'=>intval($param['title_word_model']),
140
+                'search_tabu_words'=>$search_tabu_words,
141
+            ];
142
+            /*多语言*/
143
+            if (is_language()) {
144
+                $langRow = \think\Db::name('language')->order('id asc')
145
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
146
+                    ->select();
147
+                foreach ($langRow as $key => $val) {
148
+                    tpCache('search', $data, $val['mark']);
149
+                }
150
+            } else {
151
+                tpCache('search', $data);
152
+            }
153
+            /*--end*/
154
+            $this->success('操作成功');
155
+        }
156
+        $search = tpCache('search');
157
+        if (!isset($search['search_second'])) {
158
+            $search['search_second'] = 60;
159
+        }
160
+        if (!isset($search['search_maxnum'])) {
161
+            $search['search_maxnum'] = 5;
162
+        }
163
+        if (!isset($search['search_locking'])) {
164
+            $search['search_locking'] = 120;
165
+        }
166
+        if (!isset($search['search_tabu_words'])) {
167
+            $search_tabu_words = ['<','>','"',';',',','@','&'];
168
+            $search['search_tabu_words'] = implode(PHP_EOL, $search_tabu_words);
169
+        }
170
+        $this->assign('search',$search);
171
+
172
+        return $this->fetch();
173
+    }
174
+
175
+    public function batch_add()
176
+    {
177
+        if (IS_POST) {
178
+            $post = input('post.');
179
+
180
+            $word = trim($post['word']);
181
+            if (empty($word)) {
182
+                $this->error('关键词列表不能为空!');
183
+            }
184
+
185
+            $wordArr = explode("\r\n", $word);
186
+            $wordArr = array_filter($wordArr);//去除数组空值
187
+            $wordArr = array_unique($wordArr); //去重
188
+            foreach ($wordArr as $key => $val) {
189
+                $wordArr[$key] = trim($val);
190
+            }
191
+
192
+            $addData = [];
193
+            $wordList = Db::name('search_word')->where([
194
+                    'word'  => ['IN', $wordArr],
195
+                    'lang'      => $this->admin_lang,
196
+                ])->column('word');
197
+            foreach ($wordArr as $key => $val) {
198
+                if(empty($val) || in_array($val, $wordList)) continue;
199
+
200
+                $addData[] = [
201
+                    'word'               => $val,
202
+                    'searchNum'            => intval($post['searchNum']),
203
+                    'is_hot'            => intval($post['is_hot']),
204
+                    'lang'              => $this->admin_lang,
205
+                    'add_time'          => getTime(),
206
+                    'update_time'       => getTime(),
207
+                ];
208
+            }
209
+            if (!empty($addData)) {
210
+                $r = Db::name('search_word')->insertAll($addData);
211
+                if ($r !== false) {
212
+                    Cache::clear('search_word');
213
+                    adminLog('批量新增关键词:'.get_arr_column($addData, 'word'));
214
+                    $this->success('操作成功!');
215
+                } else {
216
+                    $this->error('操作失败');
217
+                }
218
+            } else {
219
+                $this->success('操作成功!');
220
+            }
221
+        }
222
+        return $this->fetch();
223
+    }
224
+
225
+    // AJAX导出搜索关键词Excel文档
226
+    public function ajax_excel_export()
227
+    {
228
+        // 设置最大内存
229
+        ini_set("memory_limit", "-1");
230
+
231
+        // 防止php超时
232
+        function_exists('set_time_limit') && set_time_limit(0);
233
+
234
+        if (file_exists('./vendor/PHPExcel.zip') && !is_dir('./vendor/PHPExcel/')) {
235
+            $zip = new \ZipArchive();//新建一个ZipArchive的对象
236
+            if ($zip->open(ROOT_PATH.'vendor'.DS.'PHPExcel.zip') === true) {
237
+                $zip->extractTo(ROOT_PATH.'vendor'.DS.'PHPExcel'.DS);
238
+                $zip->close();//关闭处理的zip文件
239
+                if (is_dir('./vendor/PHPExcel/')) {
240
+                    @unlink('./vendor/PHPExcel.zip');
241
+                }
242
+            }
243
+        }
244
+
245
+        // 执行操作
246
+        if (IS_AJAX_POST) {
247
+//            $post = input('post.');
248
+            // 查询条件
249
+            $condition['lang'] = $this->admin_lang;
250
+            $orderby = "is_hot desc, id desc";
251
+
252
+            $list = $this->searchword_db->where($condition)->order($orderby)->select();
253
+
254
+            if (empty($list)) $this->error('没有导出的数据');
255
+
256
+            // 处理订单导出数据
257
+            $ExcelData = [];
258
+            foreach ($list as $key => $value) {
259
+                // 拼装追加数据
260
+                $PushData = [
261
+                    // 订单信息
262
+                    'id'   => $value['id'],
263
+                    'word'    => $value['word'],
264
+                    'searchNum'    => $value['searchNum'],
265
+                    'is_hot' => !empty($value['is_hot']) ? '是' : '否',
266
+                    'resultNum'     => $value['resultNum'],
267
+                    'update_time' => date('Y-m-d H:i:s', $value['update_time']),
268
+                ];
269
+                // 追加数据,用于导出
270
+                array_push($ExcelData, $PushData);
271
+            }
272
+            // 导出字段设置
273
+            $ExcelField = ['id', 'word', 'searchNum', 'is_hot', 'resultNum', 'update_time'];
274
+            // 导出标题设置
275
+            $ExcelTitle = ['ID', '关键词', '搜索次数', '是否热搜', '搜索结果数量', '最后搜索时间'];
276
+
277
+            $ResultUrl = $this->PerformExport($ExcelData, $ExcelField, $ExcelTitle);
278
+        }
279
+
280
+        if (!empty($ResultUrl)) {
281
+            $this->success('正在下载', $ResultUrl);
282
+        } else {
283
+            $this->error('导出失败');
284
+        }
285
+    }
286
+
287
+    private function PerformExport($ExcelData = [], $ExcelField = [], $ExcelTitle = [])
288
+    {
289
+        // 引入SDK
290
+        vendor("PHPExcel.Classes.PHPExcel");
291
+
292
+        // Excel表格坐标
293
+        $cell_arr = ['A','B','C','D','E','F','G','H','I','J','K','L','M', 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
294
+
295
+        // 执行导出
296
+        $objPHPExcel = new \PHPExcel();
297
+        $objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')->setSize(12);
298
+
299
+        // 设置表格标题栏长度
300
+        $objActSheet = $objPHPExcel->getActiveSheet();
301
+        $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(8);
302
+        $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30);
303
+        $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(8);
304
+        $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(8);
305
+        $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(8);
306
+        $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(18);
307
+        // 设置导出表格名称
308
+        $FileName = 'search-word-'.date("YmdHis");
309
+
310
+        // 循环设置表格标题栏数据
311
+        $startRow = 1;
312
+        if(!empty($ExcelTitle) || count($ExcelTitle) > 0) {
313
+            foreach($ExcelTitle as $k => $v) {
314
+                $objActSheet->setCellValue($cell_arr[$k] . $startRow, $v);
315
+            }
316
+            $startRow = 2;
317
+        }
318
+
319
+        // 循环设置表格字段内容数据
320
+        foreach($ExcelData as $v) {
321
+            foreach($ExcelField as $key => $value) {
322
+                $objActSheet->setCellValue($cell_arr[$key] . $startRow, $v[$value]);
323
+            }
324
+            $startRow++;
325
+        }
326
+
327
+        $objPHPExcel->setActiveSheetIndex(0);
328
+        header('Content-Type: application/vnd.ms-excel');
329
+        header('Content-Disposition: attachment;filename="' . $FileName . '.xlsx"');
330
+        header('Cache-Control: max-age=0');
331
+        header('Cache-Control: max-age=1');
332
+        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
333
+        header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
334
+        header('Cache-Control: cache, must-revalidate');
335
+        header('Pragma: public');
336
+        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
337
+
338
+        // 文件目录
339
+        $ExcelPath = UPLOAD_PATH . 'excel/';
340
+        // 保存前清空删除原先的excel
341
+        delFile(UPLOAD_PATH . 'excel/', true);
342
+        // 创建文件夹
343
+        @mkdir($ExcelPath, 0777, true);
344
+        // excel文件路径
345
+        $filePath = $ExcelPath . $FileName . '.xlsx';
346
+        // 保存excel文件
347
+        $objWriter->save($filePath);
348
+        // 返回excel文件路径到AJAX下载
349
+        return request()->domain() . ROOT_DIR . '/' . $filePath;
350
+    }
351
+}
352
+

+ 1149
- 0
application/admin/controller/Security.php
File diff suppressed because it is too large
View File


+ 589
- 0
application/admin/controller/Seo.php View File

@@ -0,0 +1,589 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Cache;
18
+use app\common\logic\ArctypeLogic;
19
+use think\paginator\driver; // 生成静态页面代码
20
+use app\admin\logic\FilemanagerLogic;
21
+use app\common\logic\BuildhtmlLogic;
22
+
23
+class Seo extends Base
24
+{
25
+    private $buildhtmlLogic;
26
+
27
+    public function _initialize() {
28
+        parent::_initialize();
29
+        $this->language_access(); // 多语言功能操作权限
30
+        $this->buildhtmlLogic = new BuildhtmlLogic;
31
+    }
32
+    /*
33
+     * 生成总站
34
+     */
35
+    public function site(){
36
+        $param = input('param.');
37
+        $uphtmltype = !empty($param['uphtmltype']) ? intval($param['uphtmltype']) : 0;
38
+        $this->assign('uphtmltype', $uphtmltype);
39
+
40
+        if (!empty($param['is_buildhtml'])) {
41
+            /*多语言*/
42
+            $seoConfig = [];
43
+            $seoConfig['seo_maxpagesize'] = !empty($param['seo_maxpagesize']) ? intval($param['seo_maxpagesize']) : 50; // 栏目每页生成文件
44
+            $seoConfig['seo_pagesize'] = !empty($param['seo_pagesize']) ? intval($param['seo_pagesize']) : 20; // 文档每页生成文件
45
+            $seoConfig['seo_start_time'] = !empty($param['seo_start_time']) ? $param['seo_start_time'] : ""; // 起始时间
46
+            $seoConfig['seo_startid2'] = !empty($param['seo_startid2']) ? intval($param['seo_startid2']) : ""; // 起始id
47
+            if (is_language()) {
48
+                $langRow = \think\Db::name('language')->order('id asc')
49
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
50
+                    ->select();
51
+                foreach ($langRow as $key => $val) {
52
+                    tpCache('seo', $seoConfig, $val['mark']);
53
+                }
54
+            } else {
55
+                tpCache('seo', $seoConfig);
56
+            }
57
+            /*--end*/
58
+        }
59
+
60
+        return $this->fetch();
61
+    }
62
+    /*
63
+     * 生成栏目页
64
+     */
65
+    public function channel(){
66
+        $param = input('param.');
67
+        $typeid = !empty($param['typeid']) ? intval($param['typeid']) : 0; // 栏目ID
68
+        $this->assign('typeid', $typeid);
69
+
70
+        if (!empty($param['is_buildhtml'])) {
71
+            /*多语言*/
72
+            $seoConfig = [];
73
+            $seoConfig['seo_maxpagesize'] = !empty($param['seo_maxpagesize']) ? intval($param['seo_maxpagesize']) : 50; // 每页生成文件
74
+            $seoConfig['seo_upnext'] = isset($param['seo_upnext']) ? intval($param['seo_upnext']) : 1; // 是否更新子栏目
75
+            if (is_language()) {
76
+                $langRow = \think\Db::name('language')->order('id asc')
77
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
78
+                    ->select();
79
+                foreach ($langRow as $key => $val) {
80
+                    tpCache('seo', $seoConfig, $val['mark']);
81
+                }
82
+            } else {
83
+                tpCache('seo', $seoConfig);
84
+            }
85
+            /*--end*/
86
+        }
87
+
88
+        return $this->fetch();
89
+    }
90
+    /*
91
+     * 生成文档页
92
+     */
93
+    public function article()
94
+    {
95
+        $param = input('param.');
96
+        $typeid = !empty($param['typeid']) ? intval($param['typeid']) : 0; // 栏目ID
97
+        $this->assign('typeid', $typeid);
98
+
99
+        $uphtmltype = !empty($param['uphtmltype']) ? intval($param['uphtmltype']) : 0;
100
+        $this->assign('uphtmltype', $uphtmltype);
101
+
102
+        if (!empty($param['is_buildhtml'])) {
103
+            /*多语言*/
104
+            $seoConfig = [];
105
+            $seoConfig['seo_startid'] = !empty($param['seo_startid']) ? intval($param['seo_startid']) : 0; // 文档ID开始
106
+            $seoConfig['seo_endid'] = !empty($param['seo_endid']) ? intval($param['seo_endid']) : 0; // 文档ID结束
107
+            $seoConfig['seo_pagesize'] = !empty($param['seo_pagesize']) ? intval($param['seo_pagesize']) : 20; // 每页生成文件
108
+            if (is_language()) {
109
+                $langRow = \think\Db::name('language')->order('id asc')
110
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
111
+                    ->select();
112
+                foreach ($langRow as $key => $val) {
113
+                    tpCache('seo', $seoConfig, $val['mark']);
114
+                }
115
+            } else {
116
+                tpCache('seo', $seoConfig);
117
+            }
118
+            /*--end*/
119
+        }
120
+
121
+        return $this->fetch();
122
+    }
123
+
124
+    /**
125
+     * 初始化数据缓存
126
+     * @return [type] [description]
127
+     */
128
+    public function init_data_cache()
129
+    {
130
+        if (IS_POST) {
131
+            // 获取全部栏目的数据
132
+            $this->buildhtmlLogic->get_arctype_all();
133
+            // 获取全部文档微表的数据
134
+            $this->buildhtmlLogic->get_archives_all();
135
+
136
+            $this->success('缓存成功');
137
+        }
138
+    }
139
+
140
+    private function resetHtmlConf()
141
+    {
142
+        /*多语言*/
143
+        // 恢复设置默认值
144
+        $seoConfig = [];
145
+        $seoConfig['seo_maxpagesize'] = 50;
146
+        $seoConfig['seo_upnext'] = 1;
147
+        $seoConfig['seo_pagesize'] = 20;
148
+        if (is_language()) {
149
+            $langRow = \think\Db::name('language')->order('id asc')
150
+                ->cache(true, EYOUCMS_CACHE_TIME, 'language')
151
+                ->select();
152
+            foreach ($langRow as $key => $val) {
153
+                tpCache('seo', $seoConfig, $val['mark']);
154
+            }
155
+        } else {
156
+            tpCache('seo', $seoConfig);
157
+        }
158
+        /*--end*/
159
+
160
+        // 生成静态页面代码 - 更新分页php文件支持生成静态功能
161
+        $this->update_paginatorfile();
162
+
163
+        return $seoConfig;
164
+    }
165
+
166
+    /*
167
+     * 静态生成页面
168
+     */
169
+    public function build(){
170
+        $globalConfig = tpCache('global');
171
+
172
+        if (2 != $globalConfig['seo_pseudo']) {
173
+            $this->error('当前不是静态页面模式!');
174
+        }
175
+
176
+        // 恢复生成静态的设置默认值
177
+        $seoConfig = $this->resetHtmlConf();
178
+        $globalConfig = array_merge($globalConfig, $seoConfig);
179
+
180
+        $this->assign('config', $globalConfig);//当前配置项
181
+        // 栏目列表
182
+        $map = array(
183
+            'status'  => 1,
184
+            'is_del'  => 0, // 回收站功能
185
+            'current_channel'    => ['neq', 51], // 问答模型
186
+            'weapp_code'    => '',
187
+        );
188
+        $arctypeLogic = new ArctypeLogic();
189
+        $select_html = $arctypeLogic->arctype_list(0, 0, true, config('global.arctype_max_level'), $map);
190
+        $this->assign('select_html',$select_html);
191
+        // 允许发布文档列表的栏目
192
+        $arc_select_html = allow_release_arctype();
193
+        $this->assign('arc_select_html', $arc_select_html);
194
+
195
+        // 网站根目录缺少 index.php 文件,请拷贝该文件上传到空间里!
196
+        $is_index_file = 1;
197
+        if (!file_exists('./index.php')) {
198
+            $is_index_file = 0;
199
+        }
200
+        $this->assign('is_index_file', $is_index_file);
201
+
202
+        return $this->fetch();
203
+    }
204
+    /*
205
+     * URL配置
206
+     */
207
+    public function seo()
208
+    {
209
+        /* 纠正栏目的HTML目录路径字段值 */
210
+        $this->correctArctypeDirpath();
211
+        /* end */
212
+
213
+        $inc_type =  'seo';
214
+        $config = tpCache($inc_type);
215
+        $config['seo_pseudo'] = tpCache('global.seo_pseudo');
216
+        //前台默认语言
217
+        $default_lang = \think\Config::get('ey_config.system_home_default_lang');
218
+        $this->assign('default_lang',$default_lang);
219
+        $seo_pseudo_list = get_seo_pseudo_list();
220
+        $this->assign('seo_pseudo_list', $seo_pseudo_list);
221
+
222
+        /* 生成静态页面代码 - 多语言统一设置URL模式 */
223
+        $seo_pseudo_lang = '';
224
+        $web_language_switch = tpCache('global.web_language_switch');
225
+        if (is_language() && !empty($web_language_switch)) {
226
+            $markArr = Db::name('language')->field('mark')->order('id asc')->limit('1,1')->select();
227
+            if (!empty($markArr[0]['mark'])) {
228
+                $seo_pseudo_lang = tpCache('global.seo_pseudo', [], $markArr[0]['mark']);
229
+            }
230
+            $seo_pseudo_lang = !empty($seo_pseudo_lang) ? $seo_pseudo_lang : 1;
231
+        }
232
+        $this->assign('seo_pseudo_lang', $seo_pseudo_lang);
233
+        /* end */
234
+
235
+        /* 限制文档HTML保存路径的名称 */
236
+        $wwwroot_dir = config('global.wwwroot_dir'); // 网站根目录的目录列表
237
+        $disable_dirname = config('global.disable_dirname'); // 栏目伪静态时的路由路径
238
+        $wwwroot_dir = array_merge($wwwroot_dir, $disable_dirname);
239
+        // 不能与栏目的一级目录名称重复
240
+        $arctypeDirnames = Db::name('arctype')->where(['parent_id'=>0])->column('dirname');
241
+        is_array($arctypeDirnames) && $wwwroot_dir = array_merge($wwwroot_dir, $arctypeDirnames);
242
+        // 不能与多语言的标识重复
243
+        $markArr = Db::name('language_mark')->column('mark');
244
+        is_array($markArr) && $wwwroot_dir = array_merge($wwwroot_dir, $markArr);
245
+        $wwwroot_dir = array_unique($wwwroot_dir);
246
+        $this->assign('seo_html_arcdir_limit', implode(',', $wwwroot_dir));
247
+        /* end */
248
+
249
+        $seo_html_arcdir_1 = '';
250
+        if (!empty($config['seo_html_arcdir'])) {
251
+            $config['seo_html_arcdir'] = trim($config['seo_html_arcdir'], '/');
252
+            $seo_html_arcdir_1 = '/'.$config['seo_html_arcdir'];
253
+        }
254
+        $this->assign('seo_html_arcdir_1', $seo_html_arcdir_1);
255
+
256
+        // 栏目列表
257
+        $map = array(
258
+            'status'  => 1,
259
+            'is_del'  => 0, // 回收站功能
260
+            'current_channel'    => ['neq', 51], // 问答模型
261
+            'weapp_code'    => '',
262
+        );
263
+        $arctypeLogic = new ArctypeLogic();
264
+        $select_html = $arctypeLogic->arctype_list(0, 0, true, config('global.arctype_max_level'), $map);
265
+        $this->assign('select_html',$select_html);
266
+
267
+        // 允许发布文档列表的栏目
268
+        $arc_select_html = allow_release_arctype();
269
+        $this->assign('arc_select_html', $arc_select_html);
270
+
271
+        /*标记是否第一次切换静态页面模式*/
272
+        if (!isset($config['seo_html_arcdir'])) {
273
+            $init_html = 1; // 第一次切换
274
+        } else {
275
+            $init_html = 2; // 多次切换
276
+        }
277
+        $this->assign('init_html', $init_html);
278
+        /*--end*/
279
+
280
+        // 恢复生成静态的设置默认值
281
+        $this->resetHtmlConf();
282
+
283
+        // 网站根目录缺少 index.php 文件,请拷贝该文件上传到空间里!
284
+        $is_index_file = 1;
285
+        if (!file_exists('./index.php')) {
286
+            $is_index_file = 0;
287
+        }
288
+        $this->assign('is_index_file', $is_index_file);
289
+
290
+        $this->assign('config',$config);//当前配置项
291
+        return $this->fetch();
292
+    }
293
+
294
+    /*
295
+     * 保存URL配置
296
+     */
297
+    public function handle()
298
+    {
299
+        if (IS_POST) {
300
+            $param = input('post.');
301
+            $this->buildhtmlLogic->seo_handle($param);
302
+
303
+            // 优化数据
304
+            $this->optimizeTableData();
305
+            // 更新分页php文件支持生成静态功能
306
+            $this->update_paginatorfile();
307
+
308
+            delFile(HTML_ROOT);
309
+            \think\Cache::clear();
310
+            $this->success('操作成功', url('Seo/seo'));
311
+        }
312
+        $this->error('操作失败');
313
+    }
314
+
315
+    /**
316
+     *  优化数据
317
+     *
318
+     * @access    public
319
+     * @return    void
320
+     */
321
+    private function optimizeTableData()
322
+    {
323
+        $optimizeTableData_time = tpSetting('system.system_optimizeTableData_time', '', 'cn');
324
+        $optimizeTableData_time = intval($optimizeTableData_time) + (15 * 86400);
325
+        if (getTime() > $optimizeTableData_time) {
326
+            $tptables = ['archives'];
327
+            $row = Db::name('channeltype')->field('nid,table')->select();
328
+            foreach ($row as $key => $val) {
329
+                if (in_array($val['nid'], ['ask','guestbook'])) {
330
+                    continue;
331
+                }
332
+                $tptables[] = $val['table'].'_content';
333
+            }
334
+
335
+            $tptable = '';
336
+            foreach ($tptables as $key => $t) {
337
+                $t = PREFIX.$t;
338
+                $tptable .= ($tptable == '' ? "`{$t}`" : ",`{$t}`" );
339
+            }
340
+
341
+            try {
342
+                @Db::execute(" OPTIMIZE TABLE $tptable; ");
343
+            } catch (\Exception $e) {
344
+
345
+            }
346
+
347
+            tpSetting('system', ['system_optimizeTableData_time'=>getTime()], 'cn');
348
+        }
349
+    }
350
+
351
+    /**
352
+     * 生成静态页面代码 - 更新分页php文件支持生成静态功能
353
+     */
354
+    private function update_paginatorfile()
355
+    {
356
+        $dirpath = CORE_PATH . 'paginator/driver/*.php';
357
+        $files = glob($dirpath);
358
+        foreach ($files as $key => $file) {
359
+            if (is_writable($file)) {
360
+                $strContent = @file_get_contents($file);
361
+                if (false != $strContent && !stristr($strContent, 'data-ey_fc35fdc="html"')) {
362
+                    $replace = 'htmlentities($url) . \'" data-ey_fc35fdc="html" data-tmp="1\'';
363
+                    $strContent = str_replace('htmlentities($url)', $replace, $strContent);
364
+                    @chmod($file,0777);
365
+                    @file_put_contents($file, $strContent);
366
+                }
367
+            }
368
+        }
369
+    }
370
+
371
+    /*
372
+     * 生成整站静态文件
373
+     */
374
+    public function buildSite(){
375
+        $type =  input("param.type/s");
376
+        if($type != 'site'){
377
+            $this->error('操作失败');
378
+        }
379
+        $this->success('操作成功');
380
+    }
381
+
382
+    /*
383
+     * 获取生成栏目或文章的栏目id
384
+     */
385
+    public function getAllType(){
386
+        $id =  input("param.id/d");//栏目id
387
+        $type =  input("param.type/d");//1栏目2文章
388
+        if(empty($id)) {
389
+            if($id == 0){
390
+                $mark = Db::name('language')->order('id asc')->value('mark');
391
+                if($type == 1){
392
+                    $arctype = Db::name('arctype')->where(['is_del'=>0,'status'=>1,'lang'=>$mark])->getfield('id',true);
393
+                }else{
394
+                    $where['is_del'] = 0;
395
+                    $where['status'] = 1;
396
+                    $where['lang'] = $mark;
397
+                    $where['current_channel'] = array(array('neq',6),array('neq',8));
398
+                    $arctype = Db::name('arctype')->where($where)->getfield('id',true);
399
+                }
400
+                if(empty($arctype)){
401
+                    $this->error('没有要更新的栏目!');
402
+                }else{
403
+                    $arctype = implode(',',$arctype);
404
+                    $this->success($arctype);
405
+                }
406
+            }else{
407
+                $this->error('栏目ID不能为空!');
408
+            }
409
+        }else{
410
+            //递归查询所有的子类
411
+            $arctype_child_all = array($id);
412
+            getAllChild($arctype_child_all,$id,$type);
413
+
414
+            $arctype_child_all = implode(',',$arctype_child_all);
415
+            if(empty($arctype_child_all)) {
416
+                $this->error('没有要更新的栏目!');
417
+            }else{
418
+                $this->success($arctype_child_all);
419
+            }
420
+        }
421
+    }
422
+
423
+    /**
424
+     * 纠正栏目的HTML目录路径字段值
425
+     */
426
+    private function correctArctypeDirpath()
427
+    {
428
+        $system_correctArctypeDirpath = tpCache('global.system_correctArctypeDirpath');
429
+        if (!empty($system_correctArctypeDirpath)) {
430
+            return false;
431
+        }
432
+
433
+        $saveData = [];
434
+        $arctypeList = Db::name('arctype')->field('id,parent_id,dirname,dirpath,grade')
435
+            ->order('grade asc')
436
+            ->getAllWithIndex('id');
437
+        foreach ($arctypeList as $key => $val) {
438
+            if (empty($val['parent_id'])) { // 一级栏目
439
+                $saveData[] = [
440
+                    'id'            => $val['id'],
441
+                    'dirpath'       => '/'.$val['dirname'],
442
+                    'grade'         => 0,
443
+                    'update_time'   => getTime(),
444
+                ];
445
+            } else {
446
+                $parentRow = $arctypeList[$val['parent_id']];
447
+                if (empty($parentRow['parent_id'])) { // 二级栏目
448
+                    $saveData[] = [
449
+                        'id'            => $val['id'],
450
+                        'dirpath'       => '/'.$parentRow['dirname'].'/'.$val['dirname'],
451
+                        'grade'         => 1,
452
+                        'update_time'   => getTime(),
453
+                    ];
454
+                } else { // 三级栏目
455
+                    $topRow = $arctypeList[$parentRow['parent_id']];
456
+                    $saveData[] = [
457
+                        'id'            => $val['id'],
458
+                        'dirpath'       => '/'.$topRow['dirname'].'/'.$parentRow['dirname'].'/'.$val['dirname'],
459
+                        'grade'         => 2,
460
+                        'update_time'   => getTime(),
461
+                    ];
462
+                }
463
+            }
464
+        }
465
+        $r = model('Arctype')->saveAll($saveData);
466
+        if (false !== $r) {
467
+            /*多语言*/
468
+            if (is_language()) {
469
+                $langRow = \think\Db::name('language')->order('id asc')
470
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
471
+                    ->select();
472
+                foreach ($langRow as $key => $val) {
473
+                    tpCache('system', ['system_correctArctypeDirpath'=>1],$val['mark']);
474
+                }
475
+            } else {
476
+                tpCache('system',['system_correctArctypeDirpath'=>1]);
477
+            }
478
+            /*--end*/
479
+        }
480
+    }
481
+
482
+    /**
483
+     * 静态页面模式切换为其他模式时,检测之前生成的静态目录是否存在,并提示手工删除还是自动删除
484
+     */
485
+    public function ajax_checkHtmlDirpath()
486
+    {
487
+        $seo_pseudo_new = input('param.seo_pseudo_new/d');
488
+        if (3 == $seo_pseudo_new) {
489
+            $dirArr = [];
490
+            $seo_html_listname = tpCache('global.seo_html_listname');
491
+            $row = Db::name('arctype')->field('dirpath,diy_dirpath')->select();
492
+            foreach ($row as $key => $val) {
493
+                $dirpathArr = explode('/', $val['dirpath']);
494
+                if (3 == $seo_html_listname) {
495
+                    $dir = end($dirpathArr);
496
+                } else if (4 == $seo_html_listname) {
497
+                    $dirpathArr = explode('/', $val['diy_dirpath']);
498
+                    $dir = end($dirpathArr);
499
+                } else {
500
+                    $dir = !empty($dirpathArr[1]) ? $dirpathArr[1] : '';
501
+                }
502
+                if (!empty($dir) && !in_array($dir, $dirArr)) {
503
+                    array_push($dirArr, $dir);
504
+                }
505
+            }
506
+
507
+            $data = [];
508
+            $data['msg'] = '';
509
+            $num = 0;
510
+            $wwwroot = glob('*', GLOB_ONLYDIR);
511
+            foreach ($wwwroot as $key => $val) {
512
+                if (in_array($val, $dirArr)) {
513
+                    if (0 == $num) {
514
+                        $data['msg'] .= "<font color='red'>根目录下有HTML静态目录,请先删除:</font><br/>";
515
+                    }
516
+                    $data['msg'] .= ($num+1)."、{$val}<br/>";
517
+                    $num++;
518
+                }
519
+            }
520
+            $data['height'] = $num * 24;
521
+
522
+            $this->success('检测成功!', null, $data);
523
+        }
524
+    }
525
+
526
+    /**
527
+     * 自动删除静态HTML存放目录
528
+     */
529
+    public function ajax_delHtmlDirpath()
530
+    {
531
+        if (IS_AJAX_POST) {
532
+            $data = del_html_dirpath();
533
+            if (!empty($data['msg'])){
534
+                $this->error('删除失败!', null, $data);
535
+            }
536
+
537
+            $this->success('删除成功!', null, $data);
538
+        }
539
+    }
540
+
541
+    /*
542
+     * 选择首页模板
543
+     */
544
+    public function filemanager(){
545
+        $this->filemanagerLogic = new FilemanagerLogic();
546
+        $this->globalTpCache = $this->filemanagerLogic->globalTpCache;
547
+        $this->baseDir = $this->filemanagerLogic->baseDir; // 服务器站点根目录绝对路径
548
+        $this->maxDir = $this->filemanagerLogic->maxDir."/pc"; // 默认文件管理的最大级别目录
549
+        // 获取到所有GET参数
550
+        $param = input('param.', '', null);
551
+        $activepath = input('param.activepath', '', null);
552
+        $activepath = $this->filemanagerLogic->replace_path($activepath, ':', true);
553
+
554
+        /*当前目录路径*/
555
+        $activepath = !empty($activepath) ? $activepath : $this->maxDir;
556
+        $tmp_max_dir = preg_replace("#\/#i", "\/", $this->maxDir);
557
+        if (!preg_match("#^".$tmp_max_dir."#i", $activepath)) {
558
+            $activepath = $this->maxDir;
559
+        }
560
+        /*--end*/
561
+
562
+        $inpath = "";
563
+        $activepath = str_replace("..", "", $activepath);
564
+        $activepath = preg_replace("#^\/{1,}#", "/", $activepath); // 多个斜杆替换为单个斜杆
565
+        if($activepath == "/") $activepath = "";
566
+
567
+        if(empty($activepath)) {
568
+            $inpath = $this->baseDir.$this->maxDir;
569
+        } else {
570
+            $inpath = $this->baseDir.$activepath;
571
+        }
572
+
573
+        $list = $this->filemanagerLogic->getDirFile($inpath, $activepath);
574
+        $assign_data['list'] = $list;
575
+
576
+        /*文件操作*/
577
+        $assign_data['replaceImgOpArr'] = $this->filemanagerLogic->replaceImgOpArr;
578
+        $assign_data['editOpArr'] = $this->filemanagerLogic->editOpArr;
579
+        $assign_data['renameOpArr'] = $this->filemanagerLogic->renameOpArr;
580
+        $assign_data['delOpArr'] = $this->filemanagerLogic->delOpArr;
581
+        $assign_data['moveOpArr'] = $this->filemanagerLogic->moveOpArr;
582
+        /*--end*/
583
+
584
+        $assign_data['activepath'] = $activepath;
585
+
586
+        $this->assign($assign_data);
587
+        return $this->fetch();
588
+    }
589
+}

+ 565
- 0
application/admin/controller/Seom.php View File

@@ -0,0 +1,565 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Cache;
18
+use app\common\logic\ArctypeLogic;
19
+use think\paginator\driver; // 生成静态页面代码
20
+use app\admin\logic\FilemanagerLogic;
21
+
22
+class Seom extends Base
23
+{
24
+
25
+    public function _initialize() {
26
+        parent::_initialize();
27
+        $this->language_access(); // 多语言功能操作权限
28
+    }
29
+    /*
30
+     * 生成总站
31
+     */
32
+    public function site(){
33
+		$seo_html_arcdir = Db::name('weapp_makemhtml')->where('id',1)->value('value1'); // 源地址
34
+		$this->assign("seo_html_arcdir",$seo_html_arcdir);
35
+        $uphtmltype = input('param.uphtmltype/d');
36
+        $this->assign('uphtmltype', $uphtmltype);
37
+        return $this->fetch();
38
+    }
39
+    /*
40
+     * 生成栏目页
41
+     */
42
+    public function channel(){
43
+        $typeid = input('param.typeid/d','0'); // 栏目ID
44
+        $this->assign("typeid",$typeid);
45
+		$seo_html_arcdir = Db::name('weapp_makemhtml')->where('id',1)->value('value1'); // 源地址
46
+		$this->assign("seo_html_arcdir",$seo_html_arcdir);
47
+        return $this->fetch();
48
+    }
49
+    /*
50
+     * 生成文档页
51
+     */
52
+    public function article()
53
+    {
54
+        $typeid = input('param.typeid/d','0'); // 栏目ID
55
+        $this->assign("typeid",$typeid);
56
+		$seo_html_arcdir = Db::name('weapp_makemhtml')->where('id',1)->value('value1'); // 源地址
57
+		$this->assign("seo_html_arcdir",$seo_html_arcdir);
58
+        return $this->fetch();
59
+    }
60
+    /*
61
+     * 静态生成页面
62
+     */
63
+    public function build(){
64
+        $config = tpCache('seo');
65
+        $this->assign('config',$config);//当前配置项
66
+        // 栏目列表
67
+        $map = array(
68
+            'status'  => 1,
69
+            'is_del'  => 0, // 回收站功能
70
+            'current_channel'    => ['neq', 51], // 问答模型
71
+            'weapp_code'    => '',
72
+        );
73
+        $arctypeLogic = new ArctypeLogic();
74
+        $select_html = $arctypeLogic->arctype_list(0, 0, true, config('global.arctype_max_level'), $map);
75
+        $this->assign('select_html',$select_html);
76
+        // 允许发布文档列表的栏目
77
+        $arc_select_html = allow_release_arctype();
78
+        $this->assign('arc_select_html', $arc_select_html);
79
+
80
+        return $this->fetch();
81
+    }
82
+    /*
83
+     * URL配置
84
+     */
85
+    public function seo()
86
+    {
87
+        /* 纠正栏目的HTML目录路径字段值 */
88
+        $this->correctArctypeDirpath();
89
+        /* end */
90
+
91
+        $inc_type =  'seo';
92
+        $config = tpCache($inc_type);
93
+        $config['seo_pseudo'] = tpCache('seo.seo_pseudo');
94
+        //前台默认语言
95
+        $default_lang = \think\Config::get('ey_config.system_home_default_lang');
96
+        $this->assign('default_lang',$default_lang);
97
+        $seo_pseudo_list = get_seo_pseudo_list();
98
+        if (!empty($this->globalConfig['web_citysite_open'])) unset($seo_pseudo_list[2]); // 多站点不支持静态模式
99
+        $this->assign('seo_pseudo_list', $seo_pseudo_list);
100
+
101
+        /* 生成静态页面代码 - 多语言统一设置URL模式 */
102
+        $seo_pseudo_lang = '';
103
+        $web_language_switch = tpCache('web.web_language_switch');
104
+        if (is_language() && !empty($web_language_switch)) {
105
+            $markArr = Db::name('language')->field('mark')->order('id asc')->limit('1,1')->select();
106
+            if (!empty($markArr[0]['mark'])) {
107
+                $seo_pseudo_lang = tpCache('seo.seo_pseudo', [], $markArr[0]['mark']);
108
+            }
109
+            $seo_pseudo_lang = !empty($seo_pseudo_lang) ? $seo_pseudo_lang : 1;
110
+        }
111
+        $this->assign('seo_pseudo_lang', $seo_pseudo_lang);
112
+        /* end */
113
+
114
+        /* 限制文档HTML保存路径的名称 */
115
+        $wwwroot_dir = config('global.wwwroot_dir'); // 网站根目录的目录列表
116
+        $disable_dirname = config('global.disable_dirname'); // 栏目伪静态时的路由路径
117
+        $wwwroot_dir = array_merge($wwwroot_dir, $disable_dirname);
118
+        // 不能与栏目的一级目录名称重复
119
+        $arctypeDirnames = Db::name('arctype')->where(['parent_id'=>0])->column('dirname');
120
+        is_array($arctypeDirnames) && $wwwroot_dir = array_merge($wwwroot_dir, $arctypeDirnames);
121
+        // 不能与多语言的标识重复
122
+        $markArr = Db::name('language_mark')->column('mark');
123
+        is_array($markArr) && $wwwroot_dir = array_merge($wwwroot_dir, $markArr);
124
+        $wwwroot_dir = array_unique($wwwroot_dir);
125
+        $this->assign('seo_html_arcdir_limit', implode(',', $wwwroot_dir));
126
+        /* end */
127
+
128
+        $seo_html_arcdir_1 = '';
129
+        if (!empty($config['seo_html_arcdir'])) {
130
+            $config['seo_html_arcdir'] = trim($config['seo_html_arcdir'], '/');
131
+            $seo_html_arcdir_1 = '/'.$config['seo_html_arcdir'];
132
+        }
133
+        $this->assign('seo_html_arcdir_1', $seo_html_arcdir_1);
134
+		
135
+		 
136
+        // 栏目列表
137
+        $map = array(
138
+            'status'  => 1,
139
+            'is_del'  => 0, // 回收站功能
140
+            'current_channel'    => ['neq', 51], // 问答模型
141
+            'weapp_code'    => '',
142
+        );
143
+        $arctypeLogic = new ArctypeLogic();
144
+        $select_html = $arctypeLogic->arctype_list(0, 0, true, config('global.arctype_max_level'), $map);
145
+        $this->assign('select_html',$select_html);
146
+
147
+        // 允许发布文档列表的栏目
148
+        $arc_select_html = allow_release_arctype();
149
+        $this->assign('arc_select_html', $arc_select_html);
150
+
151
+        /*标记是否第一次切换静态页面模式*/
152
+        if (!isset($config['seo_html_arcdir'])) {
153
+            $init_html = 1; // 第一次切换
154
+        } else {
155
+            $init_html = 2; // 多次切换
156
+        }
157
+        $this->assign('init_html', $init_html);
158
+        /*--end*/
159
+
160
+        $this->assign('config',$config);//当前配置项
161
+        return $this->fetch();
162
+    }
163
+
164
+    /*
165
+     * 保存URL配置
166
+     */
167
+    public function handle()
168
+    {
169
+        if (IS_POST) {
170
+            $inc_type = 'seo';
171
+            $param = input('post.');
172
+            $globalConfig = tpCache('global');
173
+            $seo_pseudo_new = $param['seo_pseudo'];
174
+
175
+            /*伪静态格式*/
176
+            if (3 == $seo_pseudo_new && in_array($param['seo_rewrite_format'], [1,3])) {
177
+                $param['seo_rewrite_format'] = $param['seo_rewrite_view_format'];
178
+            }
179
+            /*--end*/
180
+
181
+            /* 生成静态页面代码 */
182
+            unset($param['seo_html_arcdir_limit']);
183
+            if (!empty($param['seo_html_arcdir']) && !preg_match('/^([0-9a-zA-Z\_\-\/]+)$/i', $param['seo_html_arcdir'])) {
184
+                $this->error('页面保存路径的格式错误!');
185
+            }
186
+            // if (!empty($param['seo_html_arcdir'])) {
187
+            //     if (preg_match('/^([0-9a-zA-Z\_\-\/]+)$/i', $param['seo_html_arcdir'])) {
188
+            //         // $param['seo_html_arcdir'] = ROOT_DIR.'/'.trim($param['seo_html_arcdir'], '/');
189
+            //         $param['seo_html_arcdir'] = '/'.trim($param['seo_html_arcdir'], '/');
190
+            //     } else {
191
+            //         $this->error('页面保存路径的格式错误!');
192
+            //     }
193
+            // }
194
+			//获取手机路径
195
+        $makeminfo = \think\Db::name('weapp_makemhtml')->find(1);
196
+		if($makeminfo['web_url_model']==2){
197
+	    	// $param['seo_html_arcdir'] = '';	
198
+			if(input('seo_html_arcdir')){
199
+				//生成目录改成手机端设置目录			 
200
+				 $param['seo_html_arcdir'] = '';
201
+			}else{
202
+				 $param['seo_html_arcdir'] = $makeminfo['value1'];
203
+			}
204
+		}else{
205
+			//$param['seo_html_arcdir']='/'.trim($makeminfo['value'], '/');
206
+			if(input('seo_html_arcdir')){
207
+				//生成目录改成手机端设置目录			 
208
+				 $param['seo_html_arcdir'] = '/'.trim(input('seo_html_arcdir'), '/');
209
+			}else{
210
+				 $param['seo_html_arcdir'] = $makeminfo['value1'];
211
+			}
212
+		}
213
+  
214
+
215
+
216
+					 
217
+				 
218
+					 
219
+            $seo_html_arcdir_old = !empty($globalConfig['seo_html_arcdir']) ? $globalConfig['seo_html_arcdir'] : '';
220
+            /* end */
221
+
222
+            /*检测是否开启pathinfo模式*/
223
+            try {
224
+                if (3 == $seo_pseudo_new || (1 == $seo_pseudo_new && 2 == $param['seo_dynamic_format'])) {
225
+                    $fix_pathinfo = ini_get('cgi.fix_pathinfo');
226
+                    if (stristr($_SERVER['HTTP_HOST'], '.mylightsite.com')) {
227
+                        $this->error('腾讯云空间不支持伪静态!');
228
+                    } else if ('' != $fix_pathinfo && 0 === $fix_pathinfo) {
229
+                        $this->error('空间不支持伪静态,请开启pathinfo,或者在php.ini里修改cgi.fix_pathinfo=1');
230
+                    }
231
+                }
232
+                /* 生成静态页面代码 - URL模式切换时删掉根目录下的index.html静态文件 */
233
+                if(1 == $seo_pseudo_new || 3 == $seo_pseudo_new){
234
+                    if(file_exists('./index.html')){
235
+                        @unlink('./index.html');
236
+                    }
237
+                }
238
+                /* end */
239
+            } catch (\Exception $e) {}
240
+            /*--end*/
241
+
242
+            /*强制去除index.php*/
243
+            if (isset($param['seo_force_inlet'])) {
244
+                $seo_force_inlet = $param['seo_force_inlet'];
245
+                $seo_force_inlet_old = !empty($globalConfig['seo_force_inlet']) ? $globalConfig['seo_force_inlet'] : '';
246
+                if ($seo_force_inlet_old != $seo_force_inlet) {
247
+                    $param['seo_inlet'] = $seo_force_inlet;
248
+                }
249
+            }
250
+            /*--end*/
251
+
252
+            // 发布文档后更新
253
+            $param['seo_uphtml_after_home'] = !empty($param['seo_uphtml_after_home']) ? $param['seo_uphtml_after_home'] : 0;
254
+            $param['seo_uphtml_after_channel'] = !empty($param['seo_uphtml_after_channel']) ? $param['seo_uphtml_after_channel'] : 0;
255
+            $param['seo_uphtml_after_pernext'] = !empty($param['seo_uphtml_after_pernext']) ? $param['seo_uphtml_after_pernext'] : 0;
256
+
257
+            /*多语言*/
258
+            if (is_language()) {
259
+                $seo_pseudo_lang = !empty($param['seo_pseudo_lang']) ? $param['seo_pseudo_lang'] : 1;
260
+                unset($param['seo_pseudo_lang']);
261
+                $langRow = \think\Db::name('language')->order('id asc')
262
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
263
+                    ->select();
264
+                foreach ($langRow as $key => $val) {
265
+                    if (2 != $seo_pseudo_new) { // 非生成静态模式下,所有语言的URL模式一致
266
+                        tpCache($inc_type,$param,$val['mark']);
267
+                    } else {
268
+                        if($key == 0){ // 主体语言(第一个语言)是生成静态模式
269
+                            tpCache($inc_type,$param,$val['mark']);
270
+                        }else{//其他语言统一设置URL模式非静态模式
271
+                            $param['seo_pseudo'] = $seo_pseudo_lang;
272
+                            tpCache($inc_type,$param,$val['mark']);
273
+                        }
274
+                    }
275
+                }
276
+            } else {
277
+                tpCache($inc_type,$param);
278
+            }
279
+            /*--end*/
280
+
281
+            // 优化数据
282
+            $this->optimizeTableData();
283
+
284
+            $is_buildhtml = input('is_buildhtml/d');
285
+            if (!empty($is_buildhtml) && !file_exists('./index.php')) {
286
+                $this->error('网站根目录缺少 index.php 文件,请拷贝该文件上传到空间里!');
287
+            }
288
+            $this->update_paginatorfile();
289
+
290
+            delFile(rtrim(HTML_ROOT, '/'));
291
+            \think\Cache::clear();
292
+            $this->success('操作成功', url('Seo/seo'));
293
+        }
294
+        $this->error('操作失败');
295
+    }
296
+
297
+    /**
298
+     *  优化数据
299
+     *
300
+     * @access    public
301
+     * @return    void
302
+     */
303
+    private function optimizeTableData()
304
+    {
305
+        $tptables = ['archives'];
306
+        $row = Db::name('channeltype')->field('nid,table')->select();
307
+        foreach ($row as $key => $val) {
308
+            if (in_array($val['nid'], ['ask','guestbook'])) {
309
+                continue;
310
+            }
311
+            $tptables[] = $val['table'].'_content';
312
+        }
313
+
314
+        $tptable = '';
315
+        foreach ($tptables as $key => $t) {
316
+            $t = PREFIX.$t;
317
+            $tptable .= ($tptable == '' ? "`{$t}`" : ",`{$t}`" );
318
+        }
319
+
320
+        try {
321
+            @Db::execute(" OPTIMIZE TABLE $tptable; ");
322
+        } catch (\Exception $e) {
323
+
324
+        }
325
+    }
326
+
327
+    /**
328
+     * 生成静态页面代码 - 更新分页php文件支持生成静态功能
329
+     */
330
+    private function update_paginatorfile()
331
+    {
332
+        $dirpath = CORE_PATH . 'paginator/driver/*.php';
333
+        $files = glob($dirpath);
334
+        foreach ($files as $key => $file) {
335
+            if (is_writable($file)) {
336
+                $strContent = @file_get_contents($file);
337
+                if (false != $strContent && !stristr($strContent, 'data-ey_fc35fdc="html"')) {
338
+                    $replace = 'htmlentities($url) . \'" data-ey_fc35fdc="html" data-tmp="1\'';
339
+                    $strContent = str_replace('htmlentities($url)', $replace, $strContent);
340
+                    @chmod($file,0777);
341
+                    @file_put_contents($file, $strContent);
342
+                }
343
+            }
344
+        }
345
+    }
346
+
347
+    /*
348
+     * 生成整站静态文件
349
+     */
350
+    public function buildSite(){
351
+        $type =  input("param.type/s");
352
+        if($type != 'site'){
353
+            $this->error('操作失败');
354
+        }
355
+        $this->success('操作成功');
356
+    }
357
+
358
+    /*
359
+     * 获取生成栏目或文章的栏目id
360
+     */
361
+    public function getAllType(){
362
+        $id =  input("param.id/d");//栏目id
363
+        $type =  input("param.type/d");//1栏目2文章
364
+        if(empty($id)) {
365
+            if($id == 0){
366
+                $mark = Db::name('language')->order('id asc')->value('mark');
367
+                if($type == 1){
368
+                    $arctype = Db::name('arctype')->where(['is_del'=>0,'status'=>1,'lang'=>$mark])->getfield('id',true);
369
+                }else{
370
+                    $where['is_del'] = 0;
371
+                    $where['status'] = 1;
372
+                    $where['lang'] = $mark;
373
+                    $where['current_channel'] = array(array('neq',6),array('neq',8));
374
+                    $arctype = Db::name('arctype')->where($where)->getfield('id',true);
375
+                }
376
+                if(empty($arctype)){
377
+                    $this->error('没有要更新的栏目!');
378
+                }else{
379
+                    $arctype = implode(',',$arctype);
380
+                    $this->success($arctype);
381
+                }
382
+            }else{
383
+                $this->error('栏目ID不能为空!');
384
+            }
385
+        }else{
386
+            //递归查询所有的子类
387
+            $arctype_child_all = array($id);
388
+            getAllChild($arctype_child_all,$id,$type);
389
+
390
+            $arctype_child_all = implode(',',$arctype_child_all);
391
+            if(empty($arctype_child_all)) {
392
+                $this->error('没有要更新的栏目!');
393
+            }else{
394
+                $this->success($arctype_child_all);
395
+            }
396
+        }
397
+    }
398
+
399
+    /**
400
+     * 纠正栏目的HTML目录路径字段值
401
+     */
402
+    private function correctArctypeDirpath()
403
+    {
404
+        $system_correctArctypeDirpath = tpCache('system.system_correctArctypeDirpath');
405
+        if (!empty($system_correctArctypeDirpath)) {
406
+            return false;
407
+        }
408
+
409
+        $saveData = [];
410
+        $arctypeList = Db::name('arctype')->field('id,parent_id,dirname,dirpath,grade')
411
+            ->order('grade asc')
412
+            ->getAllWithIndex('id');
413
+        foreach ($arctypeList as $key => $val) {
414
+            if (empty($val['parent_id'])) { // 一级栏目
415
+                $saveData[] = [
416
+                    'id'            => $val['id'],
417
+                    'dirpath'       => '/'.$val['dirname'],
418
+                    'grade'         => 0,
419
+                    'update_time'   => getTime(),
420
+                ];
421
+            } else {
422
+                $parentRow = $arctypeList[$val['parent_id']];
423
+                if (empty($parentRow['parent_id'])) { // 二级栏目
424
+                    $saveData[] = [
425
+                        'id'            => $val['id'],
426
+                        'dirpath'       => '/'.$parentRow['dirname'].'/'.$val['dirname'],
427
+                        'grade'         => 1,
428
+                        'update_time'   => getTime(),
429
+                    ];
430
+                } else { // 三级栏目
431
+                    $topRow = $arctypeList[$parentRow['parent_id']];
432
+                    $saveData[] = [
433
+                        'id'            => $val['id'],
434
+                        'dirpath'       => '/'.$topRow['dirname'].'/'.$parentRow['dirname'].'/'.$val['dirname'],
435
+                        'grade'         => 2,
436
+                        'update_time'   => getTime(),
437
+                    ];
438
+                }
439
+            }
440
+        }
441
+        $r = model('Arctype')->saveAll($saveData);
442
+        if (false !== $r) {
443
+            /*多语言*/
444
+            if (is_language()) {
445
+                $langRow = \think\Db::name('language')->order('id asc')
446
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
447
+                    ->select();
448
+                foreach ($langRow as $key => $val) {
449
+                    tpCache('system', ['system_correctArctypeDirpath'=>1],$val['mark']);
450
+                }
451
+            } else {
452
+                tpCache('system',['system_correctArctypeDirpath'=>1]);
453
+            }
454
+            /*--end*/
455
+        }
456
+    }
457
+
458
+    /**
459
+     * 静态页面模式切换为其他模式时,检测之前生成的静态目录是否存在,并提示手工删除还是自动删除
460
+     */
461
+    public function ajax_checkHtmlDirpath()
462
+    {
463
+        $seo_pseudo_new = input('param.seo_pseudo_new/d');
464
+        if (3 == $seo_pseudo_new) {
465
+            $dirArr = [];
466
+            $seo_html_listname = tpCache('seo.seo_html_listname');
467
+            $row = Db::name('arctype')->field('dirpath,diy_dirpath')->select();
468
+            foreach ($row as $key => $val) {
469
+                $dirpathArr = explode('/', $val['dirpath']);
470
+                if (3 == $seo_html_listname) {
471
+                    $dir = end($dirpathArr);
472
+                } else if (4 == $seo_html_listname) {
473
+                    $dirpathArr = explode('/', $val['diy_dirpath']);
474
+                    $dir = end($dirpathArr);
475
+                } else {
476
+                    $dir = !empty($dirpathArr[1]) ? $dirpathArr[1] : '';
477
+                }
478
+                if (!empty($dir) && !in_array($dir, $dirArr)) {
479
+                    array_push($dirArr, $dir);
480
+                }
481
+            }
482
+
483
+            $data = [];
484
+            $data['msg'] = '';
485
+            $num = 0;
486
+            $wwwroot = glob('*', GLOB_ONLYDIR);
487
+            foreach ($wwwroot as $key => $val) {
488
+                if (in_array($val, $dirArr)) {
489
+                    if (0 == $num) {
490
+                        $data['msg'] .= "<font color='red'>根目录下有HTML静态目录,请先删除:</font><br/>";
491
+                    }
492
+                    $data['msg'] .= ($num+1)."、{$val}<br/>";
493
+                    $num++;
494
+                }
495
+            }
496
+            $data['height'] = $num * 24;
497
+
498
+            $this->success('检测成功!', null, $data);
499
+        }
500
+    }
501
+
502
+    /**
503
+     * 自动删除静态HTML存放目录
504
+     */
505
+    public function ajax_delHtmlDirpath()
506
+    {
507
+        if (IS_AJAX_POST) {
508
+            $data = del_html_dirpath();
509
+            if (!empty($data['msg'])){
510
+                $this->error('删除失败!', null, $data);
511
+            }
512
+
513
+            $this->success('删除成功!', null, $data);
514
+        }
515
+    }
516
+
517
+    /*
518
+     * 选择首页模板
519
+     */
520
+    public function filemanager(){
521
+        $this->filemanagerLogic = new FilemanagerLogic();
522
+        $this->globalTpCache = $this->filemanagerLogic->globalTpCache;
523
+        $this->baseDir = $this->filemanagerLogic->baseDir; // 服务器站点根目录绝对路径
524
+        $this->maxDir = $this->filemanagerLogic->maxDir."/pc"; // 默认文件管理的最大级别目录
525
+        // 获取到所有GET参数
526
+        $param = input('param.', '', null);
527
+        $activepath = input('param.activepath', '', null);
528
+        $activepath = $this->filemanagerLogic->replace_path($activepath, ':', true);
529
+
530
+        /*当前目录路径*/
531
+        $activepath = !empty($activepath) ? $activepath : $this->maxDir;
532
+        $tmp_max_dir = preg_replace("#\/#i", "\/", $this->maxDir);
533
+        if (!preg_match("#^".$tmp_max_dir."#i", $activepath)) {
534
+            $activepath = $this->maxDir;
535
+        }
536
+        /*--end*/
537
+
538
+        $inpath = "";
539
+        $activepath = str_replace("..", "", $activepath);
540
+        $activepath = preg_replace("#^\/{1,}#", "/", $activepath); // 多个斜杆替换为单个斜杆
541
+        if($activepath == "/") $activepath = "";
542
+
543
+        if(empty($activepath)) {
544
+            $inpath = $this->baseDir.$this->maxDir;
545
+        } else {
546
+            $inpath = $this->baseDir.$activepath;
547
+        }
548
+
549
+        $list = $this->filemanagerLogic->getDirFile($inpath, $activepath);
550
+        $assign_data['list'] = $list;
551
+
552
+        /*文件操作*/
553
+        $assign_data['replaceImgOpArr'] = $this->filemanagerLogic->replaceImgOpArr;
554
+        $assign_data['editOpArr'] = $this->filemanagerLogic->editOpArr;
555
+        $assign_data['renameOpArr'] = $this->filemanagerLogic->renameOpArr;
556
+        $assign_data['delOpArr'] = $this->filemanagerLogic->delOpArr;
557
+        $assign_data['moveOpArr'] = $this->filemanagerLogic->moveOpArr;
558
+        /*--end*/
559
+
560
+        $assign_data['activepath'] = $activepath;
561
+
562
+        $this->assign($assign_data);
563
+        return $this->fetch();
564
+    }
565
+}

+ 737
- 0
application/admin/controller/Sharp.php View File

@@ -0,0 +1,737 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+use app\admin\logic\ShopLogic;
20
+
21
+class Sharp extends Base
22
+{
23
+    public $ShopLogic;
24
+
25
+    /**
26
+     * 构造方法
27
+     */
28
+    public function _initialize()
29
+    {
30
+        parent::_initialize();
31
+
32
+        $functionLogic = new \app\common\logic\FunctionLogic;
33
+        $functionLogic->validate_authorfile(2);
34
+        $this->ShopLogic = new ShopLogic;
35
+        
36
+        // 列出营销功能里已使用的模块
37
+        $marketFunc = $this->ShopLogic->marketLogic();
38
+        if (!in_array('sharp', $marketFunc)) {
39
+            // $this->error('内置功能已废弃!');
40
+        }
41
+        $this->assign('marketFunc', $marketFunc);
42
+    }
43
+    
44
+    /**
45
+     * 秒杀商品列表
46
+     */
47
+    public function index()
48
+    {
49
+        $list     = array();
50
+        $keywords = input('keywords/s');
51
+
52
+        $condition = array();
53
+        if (!empty($keywords)) {
54
+            $condition['b.title'] = array('LIKE', "%{$keywords}%");
55
+        }
56
+
57
+        $fields = "a.*,b.title,b.litpic";
58
+
59
+        $Db    = Db::name('sharp_goods');
60
+        $count = $Db->alias("a")->join('archives b', "a.aid=b.aid")->where($condition)->count('a.sharp_goods_id');// 查询满足要求的总记录数
61
+        $Page  = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
62
+        $list  = $Db->alias("a")->field($fields)
63
+            ->join('archives b', "a.aid=b.aid")
64
+            ->where($condition)
65
+            ->order('a.sort_order asc, a.sharp_goods_id desc')
66
+            ->limit($Page->firstRow . ',' . $Page->listRows)
67
+            ->select();
68
+
69
+        $show = $Page->show();// 分页显示输出
70
+        $this->assign('page', $show);// 赋值分页输出
71
+        $this->assign('list', $list);// 赋值数据集
72
+        $this->assign('pager', $pager);// 赋值分页对象
73
+        return $this->fetch();
74
+    }
75
+
76
+    /**
77
+     * 商品选择
78
+     * @return [type] [description]
79
+     */
80
+    public function ajax_archives_list()
81
+    {
82
+        $assign_data = array();
83
+        $condition   = array();
84
+        // 获取到所有URL参数
85
+        $param  = input('param.');
86
+        $typeid = input('param.typeid/d');
87
+
88
+        // 应用搜索条件
89
+        foreach (['keywords', 'typeid'] as $key) {
90
+            if ($key == 'keywords' && !empty($param[$key])) {
91
+                $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
92
+            } else if ($key == 'typeid' && !empty($param[$key])) {
93
+                $typeid  = $param[$key];
94
+                $hasRow  = model('Arctype')->getHasChildren($typeid);
95
+                $typeids = get_arr_column($hasRow, 'id');
96
+                /*权限控制 by 小虎哥*/
97
+                $admin_info = session('admin_info');
98
+                if (0 < intval($admin_info['role_id'])) {
99
+                    $auth_role_info = $admin_info['auth_role_info'];
100
+                    if (!empty($auth_role_info)) {
101
+                        if (isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
102
+                            $condition['a.admin_id'] = $admin_info['admin_id'];
103
+                        }
104
+                        if (!empty($auth_role_info['permission']['arctype'])) {
105
+                            if (!empty($typeid)) {
106
+                                $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
107
+                            }
108
+                        }
109
+                    }
110
+                }
111
+                /*--end*/
112
+                $condition['a.typeid'] = array('IN', $typeids);
113
+            } else if (!empty($param[$key])) {
114
+                $condition['a.' . $key] = array('eq', $param[$key]);
115
+            }
116
+        }
117
+        // 审核通过
118
+        $condition['a.arcrank'] = array('gt', -1);
119
+        /*多语言*/
120
+        $condition['a.lang'] = array('eq', $this->admin_lang);
121
+        /*回收站数据不显示*/
122
+        $condition['a.is_del']  = array('eq', 0);
123
+        $channels               = 2;
124
+        $condition['a.channel'] = $channels;
125
+
126
+        /**
127
+         * 数据查询,搜索出主键ID的值
128
+         */
129
+        $count = Db::name('archives')->alias('a')->where($condition)->count('aid');// 查询满足要求的总记录数
130
+        $Page  = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
131
+        $list  = Db::name('archives')
132
+            ->alias('a')
133
+            ->field("a.aid,a.litpic,a.title,b.typename,a.update_time")
134
+            ->where($condition)
135
+            ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
136
+            ->order('a.sort_order asc, a.aid desc')
137
+            ->limit($Page->firstRow . ',' . $Page->listRows)
138
+            ->getAllWithIndex('aid');
139
+
140
+
141
+        $show                 = $Page->show(); // 分页显示输出
142
+        $assign_data['page']  = $show; // 赋值分页输出
143
+        $assign_data['list']  = $list; // 赋值数据集
144
+        $assign_data['pager'] = $Page; // 赋值分页对象
145
+
146
+        /*允许发布文档列表的栏目*/
147
+        $allow_release_channel       = !empty($channels) ? explode(',', $channels) : [];
148
+        $assign_data['arctype_html'] = allow_release_arctype($typeid, $allow_release_channel);
149
+        /*--end*/
150
+
151
+        // 模型名称
152
+        $channeltype_ntitle = '文档';
153
+        if (!stristr($channels, ',')) {
154
+            $channeltype_row    = \think\Cache::get('extra_global_channeltype');
155
+            $channeltype_ntitle = $channeltype_row[$channels]['ntitle'];
156
+        }
157
+        $assign_data['channeltype_ntitle'] = $channeltype_ntitle;
158
+
159
+        $this->assign($assign_data);
160
+
161
+        return $this->fetch();
162
+    }
163
+
164
+    /**
165
+     * 添加秒杀商品
166
+     */
167
+    public function add()
168
+    {
169
+        if (IS_POST) {
170
+            $post = input('post.');
171
+            if (is_array($post['seckill_price'])) {
172
+                $post['is_sku'] = 1; // 多规格秒杀商品
173
+                if (is_array($post['seckill_stock'])) {
174
+                    $post['seckill_stock_total'] = 0;
175
+                    foreach ($post['seckill_stock'] as $k => $v) {
176
+                        $post['seckill_stock_total'] += $v['spec_seckill_stock'];
177
+                    }
178
+                }
179
+            }
180
+
181
+            $newData = [
182
+                'aid'           => $post['aid'],
183
+                'limit'         => $post['limit'],
184
+                'is_sku'        => isset($post['is_sku']) ? $post['is_sku'] : 0,
185
+                'seckill_stock' => is_array($post['seckill_stock']) ? $post['seckill_stock_total'] : $post['seckill_stock'],
186
+                'seckill_price' => is_array($post['seckill_price']) ? 0 : $post['seckill_price'],
187
+                'virtual_sales'         => $post['virtual_sales'],
188
+                'add_time'      => getTime(),
189
+                'update_time'   => getTime(),
190
+            ];
191
+
192
+            $insertId = Db::name('sharp_goods')->insertGetId($newData);
193
+            if (false !== $insertId) {
194
+                if (isset($post['is_sku']) && 1 == $post['is_sku']) {
195
+                    model('ProductSpecValue')->ProducSpecValueEditSave($post);
196
+                }
197
+                adminLog('新增秒杀商品:' . $insertId);
198
+                $this->success("操作成功", url('Sharp/index'));
199
+            } else {
200
+                $this->error("操作失败", url('Sharp/index'));
201
+            }
202
+            exit;
203
+        }
204
+
205
+        $id   = input('id/d');
206
+        $info = Db::name('archives')->field('aid,litpic,title,users_price')->where('aid', $id)->find();
207
+        // 获取规格数据信息
208
+        // 包含:SpecSelectName、HtmlTable、spec_mark_id_arr、preset_value
209
+        $assign_data = model('ProductSpecData')->GetSharpProductSpecData($id);
210
+        // 商城配置
211
+        $shopConfig                = getUsersConfigData('shop');
212
+        $assign_data['shopConfig'] = $shopConfig;
213
+
214
+        $this->assign('info', $info);
215
+        $this->assign($assign_data);
216
+
217
+        return $this->fetch();
218
+    }
219
+
220
+    /**
221
+     * 编辑秒杀商品
222
+     */
223
+    public function edit()
224
+    {
225
+        if (IS_POST) {
226
+            $post = input('post.');
227
+            if (is_array($post['seckill_price'])) {
228
+                $post['is_sku'] = 1; // 多规格秒杀商品
229
+                if (is_array($post['seckill_stock'])) {
230
+                    $post['seckill_stock_total'] = 0;
231
+                    foreach ($post['seckill_stock'] as $k => $v) {
232
+                        $post['seckill_stock_total'] += $v['spec_seckill_stock'];
233
+                    }
234
+                }
235
+            }
236
+
237
+            $data = [
238
+                'limit'         => $post['limit'],
239
+                'is_sku'        => isset($post['is_sku']) ? $post['is_sku'] : 0,
240
+                'seckill_stock' => is_array($post['seckill_stock']) ? $post['seckill_stock_total'] : $post['seckill_stock'],
241
+                'seckill_price' => is_array($post['seckill_price']) ? 0 : $post['seckill_price'],
242
+                'virtual_sales'         => $post['virtual_sales'],
243
+                'update_time'   => getTime(),
244
+            ];
245
+
246
+            $r = Db::name('sharp_goods')->where('sharp_goods_id', intval($post['sharp_goods_id']))->update($data);
247
+            if (false !== $r) {
248
+                if (isset($post['is_sku']) && 1 == $post['is_sku']) {
249
+                    model('ProductSpecValue')->ProducSpecValueEditSave($post);
250
+                }
251
+                adminLog('编辑秒杀商品:' . $post['sharp_goods_id']);
252
+                $this->success("操作成功", url('Sharp/index'));
253
+            } else {
254
+                $this->error("操作失败", url('Sharp/index'));
255
+            }
256
+            exit;
257
+        }
258
+
259
+        $id   = input('id/d'); //指sharp_goods_id
260
+        $info = Db::name('sharp_goods')
261
+            ->alias('a')
262
+            ->field('a.*,b.litpic,b.title,b.users_price')
263
+            ->join('archives b', 'a.aid = b.aid')
264
+            ->where('a.sharp_goods_id', $id)
265
+            ->find();
266
+        // 获取规格数据信息
267
+        // 包含:SpecSelectName、HtmlTable、spec_mark_id_arr、preset_value
268
+        $assign_data = model('ProductSpecData')->GetSharpProductSpecData($info['aid']);
269
+        // 商城配置
270
+        $shopConfig                = getUsersConfigData('shop');
271
+        $assign_data['shopConfig'] = $shopConfig;
272
+
273
+        $this->assign('info', $info);
274
+        $this->assign($assign_data);
275
+
276
+        return $this->fetch();
277
+    }
278
+
279
+    /**
280
+     * 删除秒杀商品
281
+     */
282
+    public function del()
283
+    {
284
+        if (IS_POST) {
285
+            $id_arr = input('del_id/a');
286
+            $id_arr = eyIntval($id_arr);
287
+            if (!empty($id_arr)) {
288
+                $aids = Db::name('sharp_goods')
289
+                    ->where('sharp_goods_id', 'IN', $id_arr)
290
+                    ->column('aid');
291
+
292
+                $r = Db::name('sharp_goods')
293
+                    ->where('sharp_goods_id', 'IN', $id_arr)
294
+                    ->delete();
295
+                if ($r) {
296
+                    Db::name('product_spec_value')
297
+                        ->where('aid', 'IN', $aids)
298
+                        ->update([
299
+                            'seckill_price' => 0,
300
+                            'seckill_stock' => 0,
301
+                            'is_seckill'    => 0,
302
+                            'update_time'   => getTime()
303
+                        ]);
304
+                    adminLog('删除秒杀商品,aid:' . implode(',', $aids));
305
+                    $this->success('删除成功');
306
+                } else {
307
+                    $this->error('删除失败');
308
+                }
309
+            } else {
310
+                $this->error('参数有误');
311
+            }
312
+        }
313
+        $this->error('非法访问');
314
+    }
315
+
316
+    /**
317
+     * 活动会场列表
318
+     * @return mixed
319
+     */
320
+    public function active_index()
321
+    {
322
+        $list = array();
323
+//        $keywords = input('keywords/s');
324
+//
325
+        $condition = array();
326
+//        if (!empty($keywords)) {
327
+//            $condition['title'] = array('LIKE', "%{$keywords}%");
328
+//        }
329
+
330
+        $Db    = Db::name('sharp_active');
331
+        $count = $Db->where($condition)->count('active_id');// 查询满足要求的总记录数
332
+        $Page  = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
333
+        $list  = $Db
334
+            ->where($condition)
335
+            ->order('active_date desc')
336
+            ->limit($Page->firstRow . ',' . $Page->listRows)
337
+            ->getAllWithIndex('active_id');
338
+
339
+        $ids = [];
340
+        foreach ($list as $k => $v) {
341
+            $ids[] = $v['active_id'];
342
+        }
343
+        if (!empty($ids)) {
344
+            $count = Db::name('sharp_active_time')->where('active_id', 'in', $ids)->field('count(*) as count,active_id')->group('active_id')->select();
345
+            if (!empty($count)) {
346
+                foreach ($count as $k => $v) {
347
+                    $list[$v['active_id']]['count'] = $v['count'];
348
+                }
349
+            }
350
+        }
351
+        $show = $Page->show();// 分页显示输出
352
+        $this->assign('page', $show);// 赋值分页输出
353
+        $this->assign('list', $list);// 赋值数据集
354
+        $this->assign('pager', $pager);// 赋值分页对象
355
+        return $this->fetch();
356
+    }
357
+
358
+    /**
359
+     * 添加活动场次
360
+     */
361
+    public function active_add()
362
+    {
363
+        if (IS_POST) {
364
+            $post = input('post.');
365
+            if ($post['active_date'] < date('Y-m-d')) {
366
+                $this->error('活动日期不能小于当前日期!');
367
+            }
368
+            //先查询该活动日期场次是否已经存在
369
+            $have = Db::name('sharp_active')->where('active_date',strtotime($post['active_date']))->find();
370
+            if (!empty($have)){
371
+                $insertId = $have['active_id'];
372
+            }else{
373
+                $activeData = [
374
+                    'active_date' => strtotime($post['active_date']),
375
+                    'add_time'    => getTime(),
376
+                    'update_time' => getTime(),
377
+                ];
378
+                $insertId   = Db::name('sharp_active')->insertGetId($activeData);
379
+            }
380
+            if (false !== $insertId) {
381
+                //查出已经建立的秒杀活动时间
382
+                $have_time = Db::name('sharp_active_time')
383
+                    ->where('active_time','in',$post['active_time'])
384
+                    ->where('active_id',$insertId)
385
+                    ->column('active_time');
386
+                $activeTime = [];
387
+                foreach ($post['active_time'] as $v) {
388
+                    if (in_array($v,$have_time)){
389
+                        //已经存在,则跳过
390
+                        continue;
391
+                    }
392
+                    $activeTime[] = [
393
+                        'active_time' => $v,
394
+                        'active_id'   => $insertId,
395
+                        'add_time'    => getTime(),
396
+                        'update_time' => getTime(),
397
+                    ];
398
+                }
399
+                $sharpActiveTimeModel = new \app\admin\model\SharpActiveTime();
400
+                $timeData             = $sharpActiveTimeModel->saveAll($activeTime);
401
+                if ($timeData && $post['goods']) {
402
+                    $goodsData = [];
403
+                    foreach ($timeData as $k1 => $v1) {
404
+                        foreach ($post['goods']['sharp_goods_id'] as $k => $v) {
405
+                            $goodsData[] = [
406
+                                'active_time_id' => $v1->getData('active_time_id'),
407
+                                'active_id'      => $insertId,
408
+                                'sharp_goods_id' => $v,
409
+                                'aid'            => $post['goods']['aid'][$k],
410
+                                'add_time'       => getTime(),
411
+                                'update_time'    => getTime(),
412
+                            ];
413
+                        }
414
+                    }
415
+                    Db::name('sharp_active_goods')->insertAll($goodsData);
416
+                }
417
+                adminLog('新增活动场次:' . $insertId);
418
+                $this->success("操作成功", url('Sharp/active_index'));
419
+            } else {
420
+                $this->error("操作失败", url('Sharp/index'));
421
+            }
422
+            exit;
423
+        }
424
+        return $this->fetch();
425
+    }
426
+
427
+    /**
428
+     * 删除活动会场
429
+     */
430
+    public function active_del()
431
+    {
432
+        if (IS_POST) {
433
+            $id_arr = input('del_id/a');
434
+            $id_arr = eyIntval($id_arr);
435
+            if (!empty($id_arr)) {
436
+                $r = Db::name('sharp_active')
437
+                    ->where('active_id', 'IN', $id_arr)
438
+                    ->delete();
439
+                if ($r) {
440
+                    Db::name('sharp_active_time')
441
+                        ->where('active_id', 'IN', $id_arr)
442
+                        ->delete();
443
+                    Db::name('sharp_active_goods')
444
+                        ->where('active_id', 'IN', $id_arr)
445
+                        ->delete();
446
+                    adminLog('删除活动会场,active_id:' . implode(',', $id_arr));
447
+                    $this->success('删除成功');
448
+                } else {
449
+                    $this->error('删除失败');
450
+                }
451
+            } else {
452
+                $this->error('参数有误');
453
+            }
454
+        }
455
+        $this->error('非法访问');
456
+    }
457
+
458
+    /**
459
+     * 秒杀商品选择
460
+     * @return [type] [description]
461
+     */
462
+    public function goods_list()
463
+    {
464
+        $assign_data = array();
465
+        $condition   = array();
466
+        // 获取到所有URL参数
467
+        $param  = input('param.');
468
+        $typeid = input('param.typeid/d');
469
+
470
+        // 应用搜索条件
471
+        foreach (['keywords', 'typeid'] as $key) {
472
+            if ($key == 'keywords' && !empty($param[$key])) {
473
+                $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
474
+            } else if ($key == 'typeid' && !empty($param[$key])) {
475
+                $typeid  = $param[$key];
476
+                $hasRow  = model('Arctype')->getHasChildren($typeid);
477
+                $typeids = get_arr_column($hasRow, 'id');
478
+                /*权限控制 by 小虎哥*/
479
+                $admin_info = session('admin_info');
480
+                if (0 < intval($admin_info['role_id'])) {
481
+                    $auth_role_info = $admin_info['auth_role_info'];
482
+                    if (!empty($auth_role_info)) {
483
+                        if (isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
484
+                            $condition['a.admin_id'] = $admin_info['admin_id'];
485
+                        }
486
+                        if (!empty($auth_role_info['permission']['arctype'])) {
487
+                            if (!empty($typeid)) {
488
+                                $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
489
+                            }
490
+                        }
491
+                    }
492
+                }
493
+                /*--end*/
494
+                $condition['a.typeid'] = array('IN', $typeids);
495
+            }
496
+        }
497
+        /*回收站数据不显示*/
498
+        $where['b.is_del'] = 0;
499
+        $where['b.status'] = 1;
500
+
501
+        /**
502
+         * 数据查询,搜索出主键ID的值
503
+         */
504
+        $count = Db::name('sharp_goods')->alias('b')->where($where)->count('aid');// 查询满足要求的总记录数
505
+        $Page  = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
506
+        $list  = Db::name('sharp_goods')
507
+            ->alias('b')
508
+            ->field("a.litpic,a.title,b.sharp_goods_id,b.aid,b.update_time,b.seckill_stock,b.limit")
509
+            ->where($where)
510
+            ->where($condition)
511
+            ->join('archives a', 'a.aid = b.aid', 'LEFT')
512
+            ->join('arctype c', 'a.typeid = c.id', 'LEFT')
513
+            ->order('b.sort_order asc, b.sharp_goods_id desc')
514
+            ->limit($Page->firstRow . ',' . $Page->listRows)
515
+            ->getAllWithIndex('aid');
516
+        if ($list) {
517
+            foreach ($list as $key => $val) {
518
+                $val['litpic']             = get_default_pic($val['litpic']);
519
+                $json_encode_params        = [
520
+                    'sharp_goods_id' => $val['sharp_goods_id'],
521
+                    'aid'            => $val['aid'],
522
+                    'title'          => $val['title'],
523
+                    'litpic'         => $val['litpic'],
524
+                ];
525
+                $val['json_encode_params'] = json_encode($json_encode_params, JSON_UNESCAPED_SLASHES);
526
+                $list[$key]                = $val;
527
+            }
528
+        }
529
+
530
+        $show                 = $Page->show(); // 分页显示输出
531
+        $assign_data['page']  = $show; // 赋值分页输出
532
+        $assign_data['list']  = $list; // 赋值数据集
533
+        $assign_data['pager'] = $Page; // 赋值分页对象
534
+
535
+        $channels = 2;
536
+        /*允许发布文档列表的栏目*/
537
+        $allow_release_channel       = !empty($channels) ? explode(',', $channels) : [];
538
+        $assign_data['arctype_html'] = allow_release_arctype($typeid, $allow_release_channel);
539
+        /*--end*/
540
+
541
+        $this->assign($assign_data);
542
+
543
+        return $this->fetch();
544
+    }
545
+
546
+    /**
547
+     * 活动会场-场次列表
548
+     * @return mixed
549
+     */
550
+    public function active_time_index()
551
+    {
552
+        $list = [];
553
+        $where = [];
554
+        $active_id = input('id/d');
555
+        $where['a.active_id'] = $active_id;
556
+        $Db        = Db::name('sharp_active_time')->alias('a');
557
+        $count     = $Db->where($where)->count('a.active_time_id');// 查询满足要求的总记录数
558
+
559
+        $Page      = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
560
+        $list      = Db::name('sharp_active_time')->alias('a')
561
+            ->where($where)
562
+            ->field('a.*,b.active_date')
563
+            ->join('sharp_active b','a.active_id = b.active_id')
564
+            ->order('a.active_time asc')
565
+            ->limit($Page->firstRow . ',' . $Page->listRows)
566
+            ->getAllWithIndex('active_time_id');
567
+
568
+        $ids = [];
569
+        foreach ($list as $k => $v) {
570
+            if ($v['active_time']<10){
571
+                $list[$k]['active_time'] = '0'.$v['active_time'].':00';
572
+            }else{
573
+                $list[$k]['active_time'] = $v['active_time'].':00';
574
+            }
575
+            $ids[] = $v['active_time_id'];
576
+        }
577
+        if (!empty($ids)) {
578
+            $count = Db::name('sharp_active_goods')
579
+                ->where('active_id', $active_id)
580
+                ->where('active_time_id', 'in', $ids)
581
+                ->field('count(*) as count,active_time_id')
582
+                ->group('active_time_id')->select();
583
+            if (!empty($count)) {
584
+                foreach ($count as $k => $v) {
585
+                    $list[$v['active_time_id']]['count'] = $v['count'];
586
+                }
587
+            }
588
+        }
589
+        $show = $Page->show();// 分页显示输出
590
+        $this->assign('page', $show);// 赋值分页输出
591
+        $this->assign('list', $list);// 赋值数据集
592
+        $this->assign('pager', $pager);// 赋值分页对象
593
+        return $this->fetch();
594
+    }
595
+
596
+    /**
597
+     * 删除活动场次
598
+     */
599
+    public function active_time_del()
600
+    {
601
+        if (IS_POST) {
602
+            $id_arr = input('del_id/a');
603
+            $id_arr = eyIntval($id_arr);
604
+            if (!empty($id_arr)) {
605
+                $r = Db::name('sharp_active_time')
606
+                    ->where('active_time_id', 'IN', $id_arr)
607
+                    ->delete();
608
+                if ($r) {
609
+                    Db::name('sharp_active_goods')
610
+                        ->where('active_time_id', 'IN', $id_arr)
611
+                        ->delete();
612
+                    adminLog('删除活动场次,active_time_id:' . implode(',', $id_arr));
613
+                    $this->success('删除成功');
614
+                } else {
615
+                    $this->error('删除失败');
616
+                }
617
+            } else {
618
+                $this->error('参数有误');
619
+            }
620
+        }
621
+        $this->error('非法访问');
622
+    }
623
+
624
+    /**
625
+     * 编辑活动场次
626
+     */
627
+    public function active_time_edit()
628
+    {
629
+        if(IS_POST){
630
+            $post = input('post.');
631
+            if (!empty($post['goods'])){
632
+                Db::name('sharp_active_goods')
633
+                    ->where(['active_id'=>intval($post['active_id']),'active_time_id'=>intval($post['active_time_id'])])
634
+                    ->delete();
635
+                $goodsData = [];
636
+                foreach ($post['goods']['sharp_goods_id'] as $k => $v) {
637
+                    $goodsData[] = [
638
+                        'active_time_id' => $post['active_time_id'],
639
+                        'active_id'      => $post['active_id'],
640
+                        'sharp_goods_id' => $v,
641
+                        'aid'            => $post['goods']['aid'][$k],
642
+                        'add_time'       => getTime(),
643
+                        'update_time'    => getTime(),
644
+                    ];
645
+                }
646
+                $r = Db::name('sharp_active_goods')->insertAll($goodsData);
647
+                if ($r){
648
+                    adminLog('编辑活动场次active_time_id:' . $post['active_time_id']);
649
+                    $this->success("操作成功", url('Sharp/active_time_index',['id'=>$post['active_id']]));
650
+                } else {
651
+                    $this->error("操作失败", url('Sharp/active_time_edit',['id'=>$post['active_time_id']]));
652
+                }
653
+            }
654
+        }
655
+        $id = input('id/d');
656
+        $info = Db::name('sharp_active_time')->alias('a')
657
+            ->where('active_time_id',$id)
658
+            ->field('a.*,b.active_date')
659
+            ->join('sharp_active b','a.active_id = b.active_id')
660
+            ->order('a.active_time asc')
661
+            ->find();
662
+        if ($info['active_time']<10){
663
+            $info['active_time'] = '0'.$info['active_time'].':00';
664
+        }else{
665
+            $info['active_time'] = $info['active_time'].':00';
666
+        }
667
+        $goods = Db::name('sharp_active_goods')
668
+            ->alias('a')
669
+            ->field('a.*,b.litpic,b.title')
670
+            ->join('archives b','a.aid=b.aid')
671
+            ->where('a.active_time_id',$id)
672
+            ->select();
673
+        $this->assign('info',$info);
674
+        $this->assign('goods',$goods);
675
+        return $this->fetch();
676
+
677
+    }
678
+
679
+    /**
680
+     * 活动会场-添加场次
681
+     * @return mixed
682
+     */
683
+    public function active_time_add()
684
+    {
685
+        if(IS_POST){
686
+            $post = input('post.');
687
+            if(!empty($post['active_time'])){
688
+                foreach ($post['active_time'] as $v) {
689
+                    $activeTime[] = [
690
+                        'active_time' => $v,
691
+                        'active_id'   => $post['active_id'],
692
+                        'add_time'    => getTime(),
693
+                        'update_time' => getTime(),
694
+                    ];
695
+                }
696
+                $sharpActiveTimeModel = new \app\admin\model\SharpActiveTime();
697
+                $timeData             = $sharpActiveTimeModel->saveAll($activeTime);
698
+                if ($timeData && $post['goods']) {
699
+                    $goodsData = [];
700
+                    $active_time_ids = [];
701
+                    foreach ($timeData as $k1 => $v1) {
702
+                        foreach ($post['goods']['sharp_goods_id'] as $k => $v) {
703
+                            $active_time_id = $v1->getData('active_time_id');
704
+                            $active_time_ids[] = $active_time_id;
705
+                            $goodsData[] = [
706
+                                'active_time_id' => $active_time_id,
707
+                                'active_id'      => $post['active_id'],
708
+                                'sharp_goods_id' => $v,
709
+                                'aid'            => $post['goods']['aid'][$k],
710
+                                'add_time'       => getTime(),
711
+                                'update_time'    => getTime(),
712
+                            ];
713
+                        }
714
+                    }
715
+                    Db::name('sharp_active_goods')->insertAll($goodsData);
716
+                }
717
+                if ($timeData){
718
+                    adminLog('新增活动场次active_time_id:' . implode(',', $active_time_ids));
719
+                    $this->success("操作成功", url('Sharp/active_time_index',['id'=>$post['active_id']]));
720
+                }else {
721
+                    $this->error("操作失败", url('Sharp/active_time_add',['id'=>$post['active_id']]));
722
+                }
723
+
724
+            }
725
+            $this->error("请选择活动场次!", url('Sharp/active_time_add',['id'=>$post['active_id']]));
726
+
727
+        }
728
+        $active_id = input('id/d');
729
+        $info = Db::name('sharp_active')->where('active_id',$active_id)->find();
730
+        if (empty($info)){
731
+            $this->error("该活动会场不存在!", url('Sharp/active_index'));
732
+        }
733
+        $info['active_time'] = Db::name('sharp_active_time')->where('active_id',$active_id)->column('active_time');
734
+        $this->assign('info',$info);
735
+        return $this->fetch();
736
+    }
737
+}

+ 2147
- 0
application/admin/controller/Shop.php
File diff suppressed because it is too large
View File


+ 469
- 0
application/admin/controller/ShopComment.php View File

@@ -0,0 +1,469 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 陈风任 <491085389@qq.com>
11
+ * Date: 2021-01-26
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Config;
19
+use app\admin\logic\ShopLogic;
20
+
21
+class ShopComment extends Base
22
+{
23
+    // 模型ID
24
+    public $channeltype = 2;
25
+    public $ShopLogic;
26
+
27
+    public function _initialize()
28
+    {
29
+        parent::_initialize();
30
+
31
+        $functionLogic = new \app\common\logic\FunctionLogic;
32
+        $functionLogic->check_authorfile(2);
33
+
34
+        // 产品属性表
35
+        $this->shop_order_comment_db = Db::name('shop_order_comment');
36
+        $this->ShopLogic = new ShopLogic;
37
+        
38
+        // 列出营销功能里已使用的模块
39
+        $marketFunc = $this->ShopLogic->marketLogic();
40
+        $this->assign('marketFunc', $marketFunc);
41
+    }
42
+
43
+    // 评价列表
44
+    public function comment_index()
45
+    {
46
+        $functionLogic = new \app\common\logic\FunctionLogic;
47
+        $assign_data = $functionLogic->comment_index();
48
+        $this->assign($assign_data);
49
+
50
+        $shopOpenComment = getUsersConfigData('shop.shop_open_comment');
51
+        if (!empty($shopOpenComment) && 1 === intval($shopOpenComment)) {
52
+            tpCache('web', ['web_shopcomment_switch' => 1]);
53
+        } else if (isset($shopOpenComment) && 0 === intval($shopOpenComment)) {
54
+            tpCache('web', ['web_shopcomment_switch' => 0]);
55
+        }
56
+        $web_shopcomment_switch = tpCache('global.web_shopcomment_switch');
57
+        $this->assign('web_shopcomment_switch', intval($web_shopcomment_switch));
58
+
59
+        return $this->fetch();
60
+    }
61
+
62
+    // 评价详情
63
+    public function comment_details()
64
+    {
65
+        $comment_id = input('param.comment_id/d');
66
+        if (!empty($comment_id)) {
67
+            // 退换货信息
68
+            $field = 'a.comment_id, a.order_id, a.users_id, a.order_code, a.product_id, a.upload_img, a.admin_reply, a.content, a.total_score, a.is_show, a.add_time, b.product_name, b.product_price, b.litpic as product_img, b.num as product_num, c.username, c.nickname, c.head_pic, d.title, d.users_price, d.litpic';
69
+            $Comment[0] = $this->shop_order_comment_db->alias('a')->where('comment_id', $comment_id)
70
+                ->field($field)
71
+                ->join('__SHOP_ORDER_DETAILS__ b', 'a.details_id = b.details_id', 'LEFT')
72
+                ->join('__USERS__ c', 'a.users_id = c.users_id')
73
+                ->join('__ARCHIVES__ d', 'a.product_id = d.aid')
74
+                ->find();
75
+            $array_new = get_archives_data($Comment, 'product_id');
76
+            $Comment = $Comment[0];
77
+            // 如果不存在商品标题则执行
78
+            if (empty($Comment['product_name'])) $Comment['product_name'] = $Comment['title'];
79
+            // 如果不存在商品价格则执行
80
+            if (empty($Comment['product_price'])) $Comment['product_price'] = $Comment['users_price'];
81
+            // 如果不存在商品数量则执行
82
+            if (empty($Comment['product_num'])) $Comment['product_num'] = 1;
83
+            // 评价上传的图片
84
+            $Comment['upload_img'] = !empty($Comment['upload_img']) ? explode(',', unserialize($Comment['upload_img'])) : [];
85
+            foreach ($Comment['upload_img'] as $key => $value) {
86
+                if (empty($value)) {
87
+                    unset($Comment['upload_img'][$key]);
88
+                } else {
89
+                    $Comment['upload_img'][$key] = handle_subdir_pic(get_default_pic($value));
90
+                }
91
+            }
92
+            // 如果不存在商品图则执行
93
+            if (empty($Comment['product_img'])) $Comment['product_img'] = $Comment['litpic'];
94
+            // 商品图片
95
+            $Comment['product_img']  = handle_subdir_pic(get_default_pic($Comment['product_img']));
96
+            // 商品链接
97
+            $Comment['arcurl'] = get_arcurl($array_new[$Comment['product_id']]);
98
+            // 商品评价评分
99
+            $Comment['order_total_score'] = Config::get('global.order_total_score')[$Comment['total_score']];
100
+            // 评价转换星级评分,注释暂停使用,显示实际星评分
101
+            // $Comment['total_score'] = GetScoreArray($Comment['total_score']);
102
+            // 评价的内容
103
+            $Comment['content'] = !empty($Comment['content']) ? htmlspecialchars_decode(unserialize($Comment['content'])) : '';
104
+            // 回复的内容
105
+            $adminReply = !empty($Comment['admin_reply']) ? unserialize($Comment['admin_reply']) : [];
106
+            $adminReply['adminReply'] = !empty($adminReply['adminReply']) ? htmlspecialchars_decode($adminReply['adminReply']) : '';
107
+            $Comment['admin_reply'] = $adminReply;
108
+            // 会员信息
109
+            // $Users = Db::name('users')->field('users_id, username, nickname, mobile')->find($Comment['users_id']);
110
+            $Comment['nickname'] = empty($Comment['nickname']) ? $Comment['username'] : $Comment['nickname'];
111
+            $Comment['head_pic'] = handle_subdir_pic(get_default_pic($Comment['head_pic']));
112
+            // 是否属于后台系统评价
113
+            $Comment['systemComment'] = 0;
114
+            if (empty($Comment['order_id']) && empty($Comment['order_code']) && empty($Comment['details_id'])) {
115
+                $Comment['systemComment'] = 1;
116
+            }
117
+            // dump($Comment);exit;
118
+            // 加载数据
119
+            // $this->assign('Users', $Users);
120
+            $this->assign('Comment', $Comment);
121
+            return $this->fetch('comment_details');
122
+        } else {
123
+            $this->error('非法访问!');
124
+        }
125
+    }
126
+
127
+    // 评价删除
128
+    public function comment_del()
129
+    {
130
+        $id_arr = input('del_id/a');
131
+        $id_arr = eyIntval($id_arr);
132
+        if(IS_POST && !empty($id_arr)){
133
+            $ResultID = $this->shop_order_comment_db->where(['comment_id' => ['IN', $id_arr]])->delete();
134
+            if (!empty($ResultID)) {
135
+                foreach ($id_arr as $key => $val) {
136
+                    cache('EyouHomeAjaxComment_' . $val, null, null, 'shop_order_comment');
137
+                }
138
+                adminLog('删除评价-id:'.implode(',', $id_arr));
139
+                $this->success('删除成功');
140
+            } else {
141
+                $this->error('删除失败');
142
+            }
143
+        }
144
+    }
145
+
146
+    // 商家回复
147
+    public function comment_admin_reply()
148
+    {
149
+        if (IS_AJAX_POST) {
150
+            $post = input('post.');
151
+            // 参数判断
152
+            empty($post['comment_id']) && $this->error('请选择回复的评价');
153
+            empty($post['admin_reply']) && $this->error('请填写回复的内容');
154
+            $time = getTime();
155
+            // 拼装评价数据
156
+            $adminReply = [
157
+                'adminReply' => $post['admin_reply'],
158
+                'replyTime' => date('Y-m-d H:i:s', $time),
159
+            ];
160
+            $update = [
161
+                'comment_id' => intval($post['comment_id']),
162
+                'admin_reply' => serialize($adminReply),
163
+                'update_time' => $time,
164
+            ];
165
+            // 添加商品自定义评价
166
+            $updateID = $this->shop_order_comment_db->update($update);
167
+            if (!empty($updateID)) {
168
+                $this->success('回复成功');
169
+            } else {
170
+                $this->error('回复失败');
171
+            }
172
+        }
173
+    }
174
+
175
+    // 评价添加
176
+    public function comment_add()
177
+    {
178
+        if (IS_AJAX_POST) {
179
+            $post = input('post.');
180
+            // 参数判断
181
+            empty($post['aid']) && $this->error('请选择商品', null, ['post'=>true]);
182
+            empty($post['users_id']) && $this->error('请选择会员', null, ['post'=>true]);
183
+            empty($post['add_time']) && $this->error('请选择评价时段');
184
+            // 评分处理
185
+            // $PostTotalScore = 1;
186
+            // if (in_array($post['total_score'], [3, 4])) {
187
+            //  $PostTotalScore = 2;
188
+            // } else if (in_array($post['total_score'], [1, 2])) {
189
+            //  $PostTotalScore = 3;
190
+            // }
191
+            // 时间处理
192
+            $PostAddTime = explode(' ~ ', $post['add_time']);
193
+            $s_time = strtotime($PostAddTime[0]);
194
+            $e_time = strtotime($PostAddTime[1]);
195
+            // 处理会员
196
+            $users_id = explode(',', $post['users_id']);
197
+            // 添加数据
198
+            $insertAll = [];
199
+            foreach ($post['content'] as $key => $value) {
200
+                // 如果没有评价内容则提示
201
+                empty($value) && $this->error('请添加评价内容', null, ['obj'=>'#comment_add_textarea_' . $key]);
202
+                // 图片处理
203
+                $upload_img = !empty($post['upload_img'][$key]) ? implode(',', $post['upload_img'][$key]) : '';
204
+                // 随机时间处理
205
+                $time = mt_rand($s_time, $e_time);
206
+                $time = !empty($time) ? $time : getTime();
207
+                // 拼装评价数据
208
+                $insertAll[] = [
209
+                    'users_id' => intval($users_id[intval($key) - 1]),
210
+                    'order_id' => 0,
211
+                    'order_code' => 0,
212
+                    'details_id' => 0,
213
+                    'product_id' => intval($post['aid']),
214
+                    'total_score' => intval($post['total_score']),
215
+                    'content' => serialize($value),
216
+                    'upload_img' => serialize($upload_img),
217
+                    'admin_reply' => '',
218
+                    'ip_address' => clientIP(),
219
+                    'is_show' => intval($post['is_show']),
220
+                    'is_anonymous' => 0,
221
+                    'is_new_comment' => 1,
222
+                    'lang' => $this->admin_lang,
223
+                    'add_time' => $time,
224
+                    'update_time' => $time,
225
+                ];
226
+            }
227
+            // 添加商品自定义评价
228
+            $insertID = $this->shop_order_comment_db->insertAll($insertAll);
229
+            if (!empty($insertID)) {
230
+                $this->success("添加成功", url('ShopComment/comment_index'));
231
+            } else {
232
+                $this->error("添加失败");
233
+            }
234
+        }
235
+
236
+        return $this->fetch();
237
+    }
238
+
239
+    public function comment_goods_list()
240
+    {
241
+        // 查询处理
242
+        $where = [];
243
+        // 关键字查询
244
+        $keywords = input('param.keywords', '');
245
+        if (!empty($keywords)) $where['a.title'] = ['LIKE', "%{$keywords}%"];
246
+        // 栏目查询
247
+        $typeids = Db::name('arctype')->where('current_channel', $this->channeltype)->column('id');
248
+        if (!empty($typeids)) $where['a.typeid'] = ['IN', $typeids];
249
+        // 合并查询条件
250
+        $where = array_merge($where, ['a.channel' => $this->channeltype, 'a.lang' => $this->admin_lang, 'a.is_del' => 0]);
251
+        $whereNew = "(a.users_id = 0 OR (a.users_id > 0 AND a.arcrank >= 0))";
252
+
253
+        // 数据查询,搜索出主键ID的值
254
+        $SqlQuery = Db::name('archives')->alias('a')->where($where)->where($whereNew)->fetchSql()->count('aid');
255
+        $count = Db::name('sql_cache_table')->where(['sql_md5'=>md5($SqlQuery)])->getField('sql_result');
256
+        $count = ($count < 0) ? 0 : $count;
257
+        if (empty($count)) {
258
+            $count = Db::name('archives')->alias('a')->where($where)->where($whereNew)->count('aid');
259
+            /*添加查询执行语句到mysql缓存表*/
260
+            $SqlCacheTable = [
261
+                'sql_name' => '|product|' . $this->channeltype . '|',
262
+                'sql_result' => $count,
263
+                'sql_md5' => md5($SqlQuery),
264
+                'sql_query' => $SqlQuery,
265
+                'add_time' => getTime(),
266
+                'update_time' => getTime(),
267
+            ];
268
+            if (!empty($keywords)) $SqlCacheTable['sql_name'] = '|product|keywords|';
269
+            Db::name('sql_cache_table')->insertGetId($SqlCacheTable);
270
+            /*END*/
271
+        }
272
+
273
+        // 自定义排序
274
+        $orderby = input('param.orderby/s');
275
+        $orderway = input('param.orderway/s');
276
+        if (!empty($orderby) && !empty($orderway)) {
277
+            $orderby = "a.{$orderby} {$orderway}, a.aid desc";
278
+        } else {
279
+            $orderby = "a.aid desc";
280
+        }
281
+
282
+        // 查询商品数据
283
+        $Page = new Page($count, config('paginate.list_rows'));
284
+        $list = [];
285
+        if (!empty($count)) {
286
+            $limit = $count > config('paginate.list_rows') ? $Page->firstRow.','.$Page->listRows : $count;
287
+            $list = Db::name('archives')
288
+                ->field("a.aid")
289
+                ->alias('a')
290
+                ->where($where)
291
+                ->where($whereNew)
292
+                ->order($orderby)
293
+                ->limit($limit)
294
+                ->getAllWithIndex('aid');
295
+            if (!empty($list)) {
296
+                $aids = array_keys($list);
297
+                $fields = "b.*, a.*, a.aid as aid";
298
+                $row = Db::name('archives')
299
+                    ->field($fields)
300
+                    ->alias('a')
301
+                    ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
302
+                    ->where('a.aid', 'in', $aids)
303
+                    ->getAllWithIndex('aid');
304
+                foreach ($list as $key => $val) {
305
+                    $row[$val['aid']]['arcurl'] = get_arcurl($row[$val['aid']]);
306
+                    $row[$val['aid']]['litpic'] = get_default_pic($row[$val['aid']]['litpic']);
307
+                    $list[$key] = $row[$val['aid']];
308
+                }
309
+            }
310
+        }
311
+
312
+        $assign_data['page'] = $Page->show();
313
+        $assign_data['list'] = $list;
314
+        $assign_data['pager'] = $Page;
315
+        $this->assign($assign_data);
316
+        return $this->fetch();
317
+    }
318
+
319
+    public function comment_users_list()
320
+    {
321
+        // 查询处理
322
+        $where = [];
323
+        // 关键字查询
324
+        $keywords = input('param.keywords/s', '');
325
+        if (!empty($keywords)) $where['a.username|a.nickname|a.mobile|a.email|a.users_id'] = ['LIKE', "%{$keywords}%"];
326
+        // 会员等级
327
+        $level = input('param.level/d', 0);
328
+        if (!empty($level)) $where['a.level'] = $level;
329
+        // 合并查询条件
330
+        $where = array_merge($where, ['a.lang' => $this->admin_lang, 'a.is_del' => 0]);
331
+
332
+        // 查询会员信息
333
+        $count = Db::name('users')->alias('a')->where($where)->count();
334
+        $Page = new Page($count, config('paginate.list_rows'));
335
+        $list = Db::name('users')->field('a.*, b.level_name')
336
+            ->alias('a')
337
+            ->join('__USERS_LEVEL__ b', 'a.level = b.level_id', 'LEFT')
338
+            ->where($where) 
339
+            ->order('a.users_id desc')
340
+            ->limit($Page->firstRow.','.$Page->listRows)
341
+            ->select();
342
+        $users_ids = [];
343
+        foreach ($list as $key => $value) {
344
+            $users_ids[] = $value['users_id'];
345
+            $value['username'] = !empty($value['nickname']) ? $value['nickname'] : $value['username'];
346
+            $value['head_pic'] = get_head_pic($value['head_pic']);
347
+            $list[$key] = $value;
348
+        }
349
+        $this->assign('list', $list);
350
+        $this->assign('pager', $Page);
351
+        $this->assign('page', $Page->show());
352
+
353
+        // 微信登录插件
354
+        $wxlogin = [];
355
+        if (is_dir('./weapp/WxLogin/')) {
356
+            $wxlogin = Db::name('weapp_wxlogin')->where(['users_id'=>['IN', $users_ids]])->getAllWithIndex('users_id');
357
+        }
358
+        $this->assign('wxlogin', $wxlogin);
359
+        
360
+        // QQ登录插件
361
+        $qqlogin = [];
362
+        if (is_dir('./weapp/QqLogin/')) {
363
+            $qqlogin = Db::name('weapp_qqlogin')->where(['users_id'=>['IN', $users_ids]])->getAllWithIndex('users_id');
364
+        }
365
+        $this->assign('qqlogin', $qqlogin);
366
+
367
+        // 计算会员人数
368
+        $levelCountList = [
369
+            'all' => [
370
+                'level_id'      => 0,
371
+                'level_name'    => '全部会员',
372
+                'level_count'   => 0,
373
+            ],
374
+        ];
375
+        $LevelData = model('UsersLevel')->getList('level_id, level_name', [], 'level_id');
376
+        $levelCountRow = Db::name('users')->field('count(users_id) as num, level')->order('level asc')->group('level')->getAllWithIndex('level');
377
+        foreach ($LevelData as $key => $val) {
378
+            $level_num = empty($levelCountRow[$val['level_id']]) ? 0 : $levelCountRow[$val['level_id']]['num'];
379
+            $levelCountList[$val['level_id']] = [
380
+                'level_id'      => $val['level_id'],
381
+                'level_name'    => $val['level_name'],
382
+                'level_count'   => $level_num,
383
+            ];
384
+            $levelCountList['all']['level_count'] += $level_num;
385
+        }
386
+        $this->assign('levelCountList', $levelCountList);
387
+
388
+        return $this->fetch();
389
+    }
390
+
391
+    // 评价添加
392
+    public function comment_edit()
393
+    {
394
+        if (IS_AJAX_POST) {
395
+            $post = input('post.');
396
+            // 参数判断
397
+            empty($post['content']) && $this->error('请添加评价内容');
398
+            if (!empty($post['isPost'])) {
399
+                empty($post['add_time']) && $this->error('请选择评价时段');
400
+                // 评分处理
401
+                // $PostTotalScore = 1;
402
+                // if (in_array($post['total_score'], [3, 4])) {
403
+                //  $PostTotalScore = 2;
404
+                // } else if (in_array($post['total_score'], [1, 2])) {
405
+                //  $PostTotalScore = 3;
406
+                // }
407
+                // 图片处理
408
+                $upload_img = !empty($post['upload_img']) ? implode(',', $post['upload_img']) : '';
409
+                // 拼装评价数据
410
+                $update = [
411
+                    'comment_id' => intval($post['comment_id']),
412
+                    'total_score' => intval($post['total_score']),
413
+                    'content' => serialize($post['content']),
414
+                    'upload_img' => serialize($upload_img),
415
+                    'ip_address' => clientIP(),
416
+                    'is_show' => intval($post['is_show']),
417
+                    'add_time' => strtotime($post['add_time']),
418
+                    'update_time' => getTime(),
419
+                ];
420
+            } else {
421
+                $upload_img = !empty($post['upload_img']) ? implode(',', $post['upload_img']) : '';
422
+                $update = [
423
+                    'comment_id' => intval($post['comment_id']),
424
+                    'content' => serialize($post['content']),
425
+                    'is_show' => intval($post['is_show']),
426
+                    'upload_img' => serialize($upload_img),
427
+                    'update_time' => getTime(),
428
+                ];
429
+            }
430
+            // 添加商品自定义评价
431
+            $updateID = $this->shop_order_comment_db->update($update);
432
+            if (!empty($updateID)) {
433
+                $this->success("编辑成功", url('ShopComment/comment_index'));
434
+            } else {
435
+                $this->error("编辑失败");
436
+            }
437
+        }
438
+    }
439
+
440
+    /**
441
+     * 开启/关闭评价模块功能
442
+     * @return [type] [description]
443
+     */
444
+    public function ajax_open_close()
445
+    {
446
+        if (IS_AJAX_POST) {
447
+            $value = input('param.value/d');
448
+            if (1 == $value) {
449
+                $web_shopcomment_switch = 0;
450
+            } else {
451
+                $web_shopcomment_switch = 1;
452
+            }
453
+            /*多语言*/
454
+            if (is_language()) {
455
+                $langRow = \think\Db::name('language')->order('id asc')
456
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
457
+                    ->select();
458
+                foreach ($langRow as $key => $val) {
459
+                    tpCache('web', ['web_shopcomment_switch'=>$web_shopcomment_switch], $val['mark']);
460
+                }
461
+            } else { // 单语言
462
+                tpCache('web', ['web_shopcomment_switch'=>$web_shopcomment_switch]);
463
+            }
464
+            /*--end*/
465
+            $this->success("操作成功");
466
+        }
467
+        $this->error("操作失败");
468
+    }
469
+}

+ 1940
- 0
application/admin/controller/ShopProduct.php
File diff suppressed because it is too large
View File


+ 376
- 0
application/admin/controller/ShopService.php View File

@@ -0,0 +1,376 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 陈风任 <491085389@qq.com>
11
+ * Date: 2019-03-26
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Config;
19
+use app\common\logic\ShopCommonLogic;
20
+
21
+class ShopService extends Base {
22
+
23
+    private $UsersConfigData = [];
24
+
25
+    /**
26
+     * 构造方法
27
+     */
28
+    public function __construct(){
29
+        parent::__construct();
30
+
31
+        // 验证功能版授权
32
+        $functionLogic = new \app\common\logic\FunctionLogic;
33
+        $functionLogic->check_authorfile(1.5);
34
+        
35
+        $this->language_access(); // 多语言功能操作权限
36
+
37
+        $this->users_db              = Db::name('users');                   // 会员信息表
38
+        $this->shop_order_service_db  = Db::name('shop_order_service');     // 订单退换明细表
39
+
40
+        // common商城业务层,前后台共用
41
+        $this->shop_common = new ShopCommonLogic();
42
+
43
+        // 会员中心配置信息
44
+        $this->UsersConfigData = getUsersConfigData('all');
45
+        $this->assign('userConfig', $this->UsersConfigData);
46
+        
47
+        // 模型是否开启
48
+        $channeltype_row = \think\Cache::get('extra_global_channeltype');
49
+        $this->assign('channeltype_row', $channeltype_row);
50
+
51
+        $this->shopOrderServiceModel = model('ShopOrderService');
52
+    }
53
+
54
+    // 退换货服务数据列表
55
+    public function after_service()
56
+    {   
57
+        $param = input('param.');
58
+
59
+        // 获取退换货服务信息
60
+        $Result = $this->shopOrderServiceModel->GetAllServiceInfo($param);
61
+        $this->assign('Service', $Result['Service']);
62
+        $this->assign('page', $Result['pageStr']);
63
+        $this->assign('pager', $Result['pageObj']);
64
+        $this->assign('pay_name', $Result['pay_name']);
65
+        $this->assign('order_terminal', $Result['order_terminal']);
66
+        $this->assign('serviceJsonArr', $Result['serviceJsonArr']);
67
+        // 售后状态
68
+        $ServiceStatus = Config::get('global.order_service_status');
69
+        $this->assign('ServiceStatus', $ServiceStatus);
70
+        // 订单状态
71
+        $admin_order_status_arr = Config::get('global.admin_order_status_arr');
72
+        $this->assign('admin_order_status_arr', $admin_order_status_arr);
73
+
74
+        // 是否开启文章付费
75
+        $channelRow = Db::name('channeltype')->where('nid', 'in',['article','download'])->getAllWithIndex('nid');
76
+        foreach ($channelRow as &$val){
77
+            if (!empty($val['data'])) $val['data'] = json_decode($val['data'], true);
78
+        }
79
+        $this->assign('channelRow', $channelRow);
80
+
81
+        // 是否开启货到付款
82
+        $shopOpenOffline = 1;
83
+        if (0 === intval($this->UsersConfigData['shop_open_offline']) || !isset($this->UsersConfigData['shop_open_offline'])) {
84
+            $shopOpenOffline = 0;
85
+        }
86
+        $this->assign('shopOpenOffline', $shopOpenOffline);
87
+        
88
+        // 是否开启微信、支付宝支付
89
+        $where = [
90
+            'status' => 1,
91
+            'pay_mark' => ['IN', ['wechat', 'alipay']]
92
+        ];
93
+        $payApiConfig = Db::name('pay_api_config')->where($where)->select();
94
+        $openWeChat = $openAliPay = 1;
95
+        foreach ($payApiConfig as $key => $value) {
96
+            $payInfo = unserialize($value['pay_info']);
97
+            if (!empty($payInfo) && isset($payInfo['is_open_wechat']) && 0 === intval($payInfo['is_open_wechat'])) {
98
+                $openWeChat = 0;
99
+            }
100
+            if (!empty($payInfo) && isset($payInfo['is_open_alipay']) && 0 === intval($payInfo['is_open_alipay'])) {
101
+                $openAliPay = 0;
102
+            }
103
+        }
104
+        $this->assign('openWeChat', $openWeChat);
105
+        $this->assign('openAliPay', $openAliPay);
106
+        
107
+        // 是否安装 可视化微信小程序(商城版),未安装开启则不显示小程序支付
108
+        $where = [
109
+            'status' => 1,
110
+            'code' => 'DiyminiproMall'
111
+        ];
112
+        $openMall = Db::name('weapp')->where($where)->count();
113
+        $this->assign('openMall', $openMall);
114
+
115
+        // 手机端后台管理插件特定使用参数
116
+        $isMobile = input('param.isMobile/d', 0);
117
+        // 如果安装手机端后台管理插件并且在手机端访问时执行
118
+        if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
119
+            $mbPage = input('param.p/d', 1);
120
+            $nullShow = intval($Result['pageObj']->totalPages) === intval($mbPage) ? 1 : 0;
121
+            $this->assign('nullShow', $nullShow);
122
+            if ($mbPage >= 2) {
123
+                return $this->display('shop/after_service_list');
124
+            } else {
125
+                return $this->display('shop/after_service');
126
+            }
127
+        } else {
128
+            return $this->fetch('after_service');
129
+        }
130
+    }
131
+
132
+    // 退换货服务数据详情
133
+    public function after_service_details()
134
+    {
135
+        $service_id = input('param.service_id/d');
136
+        if (!empty($service_id)) {
137
+            // 查询服务信息
138
+            $Result = $this->shopOrderServiceModel->GetFieldServiceInfo($service_id);
139
+            $this->assign('Log', $Result['Log']);
140
+            $this->assign('Users', $Result['Users']);
141
+            $this->assign('Order', $Result['Order']);
142
+            $this->assign('Details', $Result['Details']);
143
+            $this->assign('Service', $Result['Service']);
144
+            $this->assign('weappVerifyLog', $Result['weappVerifyLog']);
145
+            $this->assign('iframe', input('param.iframe/d', 0));
146
+
147
+            // 如果安装手机端后台管理插件并且在手机端访问时执行
148
+            $isMobile = input('param.isMobile/d', 0);
149
+            if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
150
+                return $this->display('shop/after_service_details');
151
+            } else {
152
+                return $this->fetch('after_service_details');
153
+            }
154
+        }else{
155
+            $this->error('非法访问!');
156
+        }
157
+    }
158
+
159
+    // 更新退换货信息
160
+    public function after_service_handle()
161
+    {
162
+        if (IS_AJAX_POST) {
163
+            $post = input('post.');
164
+            if (empty($post['status']) || empty($post['service_id'])) $this->error('请选择审核意见!');
165
+            if (empty($post['users_id']) || empty($post['order_id']) || empty($post['details_id'])) $this->error('数据错误,刷新重试!');
166
+
167
+            // 更新服务单数据
168
+            $result = $this->shopOrderServiceModel->afterServiceHandle($post);
169
+            if (!empty($result)) {
170
+                $this->success('操作成功!', url('ShopService/after_service'));
171
+            } else {
172
+                $this->error('操作失败!');
173
+            }
174
+        }
175
+    }
176
+
177
+    // 退款页面信息
178
+    public function after_service_refund()
179
+    {
180
+        // 查询维权订单信息
181
+        $service_id = input('param.service_id/d', 0);
182
+        $result = $this->shopOrderServiceModel->GetFieldServiceInfo($service_id);
183
+        if (empty($result)) $this->error('维权订单不存在');
184
+        $this->assign($result);
185
+
186
+        return $this->fetch();
187
+    }
188
+
189
+    // 维权订单重新发货
190
+    public function after_service_resend()
191
+    {
192
+        // 查询维权订单信息
193
+        $service_id = input('param.service_id/d', 0);
194
+        $result = $this->shopOrderServiceModel->GetFieldServiceInfo($service_id);
195
+        if (empty($result)) $this->error('维权订单不存在');
196
+        $this->assign($result);
197
+
198
+        $where = [
199
+            'is_choose' => 1,
200
+        ];
201
+        $express = Db::name('shop_express')->where($where)->order('sort_order asc, express_id asc')->select();
202
+        $this->assign('express', $express);
203
+
204
+        return $this->fetch();
205
+    }
206
+
207
+    // 更新退换货信息
208
+    public function after_service_deal_with()
209
+    {
210
+        if (IS_AJAX) {
211
+            $param = input('param.');
212
+            if (empty($param)) $this->error('请正确操作!');
213
+            if (empty($param['status'])) $this->error('请选择审核意见!');
214
+            $param['manual_refund'] = !empty($param['manual_refund']) ? $param['manual_refund'] : 0;
215
+
216
+            // 换货时,卖家发货需判断快递公司及快递单号是否为空
217
+            if (6 == $param['status']) {
218
+                // if (empty($param['delivery']['name'])) $this->error('请填写快递公司!', null, ['id'=>'name']);
219
+                // if (empty($param['delivery']['code'])) $this->error('请填写快递单号!', null, ['id'=>'code']);
220
+            }
221
+
222
+            // 更新服务单数据
223
+            $where = [
224
+                'users_id'   => $param['users_id'],
225
+                'service_id' => $param['service_id']
226
+            ];
227
+            $update = [
228
+                'update_time' => getTime(),
229
+                'status' => $param['status']
230
+            ];
231
+            if (!empty($param['admin_note'])) $update['admin_note'] = $param['admin_note'];
232
+            if (!empty($param['refund_price'])) $update['refund_balance'] = $param['refund_price'];
233
+            if (!empty($param['delivery'])) $update['admin_delivery'] = serialize($param['delivery']);
234
+            $ResultID = $this->shop_order_service_db->where($where)->update($update);
235
+
236
+            if (!empty($ResultID)) {
237
+                $ResultData['status'] = $param['status'];
238
+
239
+                // 退款回会员
240
+                if (7 == $param['status']) {
241
+                    if (!isset($param['is_refund']) || 1 == $param['is_refund']) {
242
+                        // 查询会员信息
243
+                        $field = 'users_id, username, nickname, email, mobile, users_money';
244
+                        $Users = $this->users_db->field($field)->where('users_id', $param['users_id'])->find();
245
+
246
+                        // 退款操作
247
+                        $UpDate = [
248
+                            'users_money' => Db::raw('users_money+'.($param['refund_price'])),
249
+                        ];
250
+                        $ResultID = $this->users_db->where('users_id', $param['users_id'])->update($UpDate);
251
+                        if (!empty($ResultID)) {
252
+                            // 如果没有传入订单号则查询订单号
253
+                            if (empty($param['order_code'])) {
254
+                                $param['order_code'] = Db::name('shop_order')->where('order_id', $param['order_id'])->getField('order_code');
255
+                            }
256
+                            // 添加余额记录
257
+                            UsersMoneyRecording($param['order_code'], $Users, $param['refund_price'], '商品退换货');
258
+                        }
259
+                    }
260
+                }
261
+
262
+                // 售后服务手动完成服务单并自行退款
263
+                if (in_array($param['status'], [6, 7]) && 0 == $param['is_refund'] && 1 == $param['manual_refund']) {
264
+                    $where = [
265
+                        'users_id' => $param['users_id'],
266
+                        'service_id' => $param['service_id']
267
+                    ];
268
+                    $update = [
269
+                        'manual_refund' => 1,
270
+                        'manual_time' => getTime(),
271
+                        'refund_note' => trim($param['refund_note']),
272
+                        'update_time' => getTime(),
273
+                    ];
274
+                    $this->shop_order_service_db->where($where)->update($update);
275
+                }
276
+
277
+                // 添加退换货服务记录
278
+                $this->shop_common->AddOrderServiceLog($param, 0);
279
+
280
+                // 返回结束
281
+                $this->success('操作成功!', null, $ResultData);
282
+            } else {
283
+                $this->error('操作失败!');
284
+            }
285
+        }
286
+    }
287
+
288
+    // 退换货服务数据删除
289
+    public function after_service_del()
290
+    {
291
+        $service_id = input('del_id/a');
292
+        $service_id = eyIntval($service_id);
293
+        if (IS_AJAX_POST && !empty($service_id)) {
294
+            // 条件数组
295
+            $Where = [
296
+                'lang' => $this->admin_lang,
297
+                'service_id' => ['IN', $service_id]
298
+            ];
299
+            // 查询数据
300
+            $result = $this->shop_order_service_db->field('order_code')->where($Where)->select();
301
+            $order_code_list = get_arr_column($result, 'order_code');
302
+
303
+            // 删除数据
304
+            $ResultID = $this->shop_order_service_db->where($Where)->delete();
305
+            if (!empty($ResultID)) {
306
+                // 同步删除订单下的操作记录
307
+                Db::name('shop_order_service_log')->where($Where)->delete();
308
+
309
+                // 存在adminlog日志
310
+                adminLog('删除订单:'.implode(',', $order_code_list));
311
+                $this->success('删除成功');
312
+            } else {
313
+                $this->error('删除失败');
314
+            }
315
+        }
316
+        $this->error('参数有误');
317
+    }
318
+
319
+    // 会员编辑 退货数据列表
320
+    public function users_edit_after_service()
321
+    {
322
+        $param = input('param.');
323
+
324
+        // 获取退换货服务信息
325
+        $Result = $this->shopOrderServiceModel->GetUserAllServiceInfo($param);
326
+
327
+        // 获取订单状态
328
+        $ServiceStatus = Config::get('global.order_service_status');
329
+
330
+        $this->assign('Service', $Result['Service']);
331
+        $this->assign('page', $Result['pageStr']);
332
+        $this->assign('pager', $Result['pageObj']);
333
+        $this->assign('ServiceStatus', $ServiceStatus);
334
+
335
+        // 是否开启文章付费
336
+        $channelRow = Db::name('channeltype')->where('nid', 'article')->find();
337
+        $channelRow['data'] = json_decode($channelRow['data'], true);
338
+        $this->assign('channelRow', $channelRow);
339
+
340
+        // 是否开启货到付款
341
+        $shopOpenOffline = 1;
342
+        if (0 === intval($this->UsersConfigData['shop_open_offline']) || !isset($this->UsersConfigData['shop_open_offline'])) {
343
+            $shopOpenOffline = 0;
344
+        }
345
+        $this->assign('shopOpenOffline', $shopOpenOffline);
346
+
347
+        // 是否开启微信、支付宝支付
348
+        $where = [
349
+            'status' => 1,
350
+            'pay_mark' => ['IN', ['wechat', 'alipay']]
351
+        ];
352
+        $payApiConfig = Db::name('pay_api_config')->where($where)->select();
353
+        $openWeChat = $openAliPay = 1;
354
+        foreach ($payApiConfig as $key => $value) {
355
+            $payInfo = unserialize($value['pay_info']);
356
+            if (!empty($payInfo) && isset($payInfo['is_open_wechat']) && 0 === intval($payInfo['is_open_wechat'])) {
357
+                $openWeChat = 0;
358
+            }
359
+            if (!empty($payInfo) && isset($payInfo['is_open_alipay']) && 0 === intval($payInfo['is_open_alipay'])) {
360
+                $openAliPay = 0;
361
+            }
362
+        }
363
+        $this->assign('openWeChat', $openWeChat);
364
+        $this->assign('openAliPay', $openAliPay);
365
+
366
+        // 是否安装 可视化微信小程序(商城版),未安装开启则不显示小程序支付
367
+        $where = [
368
+            'status' => 1,
369
+            'code' => 'DiyminiproMall'
370
+        ];
371
+        $openMall = Db::name('weapp')->where($where)->count();
372
+        $this->assign('openMall', $openMall);
373
+
374
+        return $this->fetch('member/edit/refund_index');
375
+    }
376
+}

+ 82
- 0
application/admin/controller/Sitemap.php View File

@@ -0,0 +1,82 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\template\driver\File;
18
+
19
+class Sitemap extends Base
20
+{
21
+    public function _initialize() {
22
+        parent::_initialize();
23
+    }
24
+
25
+    /*
26
+     * Sitemap
27
+     */
28
+    public function index()
29
+    {
30
+        $inc_type =  'sitemap';
31
+        if (IS_POST) {
32
+            $param = input('post.');
33
+            $param['sitemap_not1'] = isset($param['sitemap_not1']) ? $param['sitemap_not1'] : 0;
34
+            $param['sitemap_not2'] = isset($param['sitemap_not2']) ? $param['sitemap_not2'] : 0;
35
+            $param['sitemap_xml'] = isset($param['sitemap_xml']) ? $param['sitemap_xml'] : 0;
36
+            $param['sitemap_html'] = isset($param['sitemap_html']) ? $param['sitemap_html'] : 0;
37
+            $param['sitemap_txt'] = isset($param['sitemap_txt']) ? $param['sitemap_txt'] : 0;
38
+            $param['sitemap_archives_num'] = isset($param['sitemap_archives_num']) ? intval($param['sitemap_archives_num']) : 100;
39
+
40
+            /*多语言*/
41
+            if (is_language()) {
42
+                $langRow = \think\Db::name('language')->order('id asc')
43
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
44
+                    ->select();
45
+                foreach ($langRow as $key => $val) {
46
+                    tpCache($inc_type,$param,$val['mark']);
47
+                }
48
+            } else {
49
+                tpCache($inc_type,$param);
50
+            }
51
+            /*--end*/
52
+            
53
+            /* 生成sitemap */
54
+            sitemap_all();
55
+            $this->success('操作成功', url('Sitemap/index'));
56
+        }
57
+
58
+        $config = tpCache($inc_type);
59
+        $this->assign('config',$config);//当前配置项
60
+        if($this->globalConfig['web_mobile_domain_open']){
61
+            $mobile_domain = preg_replace('/^(.*)(\/\/)([^\/]*)(\.?)(' . request()->rootDomain() . ')(.*)$/i', '${1}${2}' . $this->globalConfig['web_mobile_domain'] . '.${5}${6}', request()->domain());
62
+            $this->assign('mobile_domain',$mobile_domain);
63
+        }
64
+        $web_basehost = preg_replace('/^(([^\:\.]+):)?(\/\/)?([^\/\:]*)(.*)$/i', '${1}${3}${4}', $this->globalConfig['web_basehost']);
65
+        $this->assign('web_basehost',$web_basehost);
66
+
67
+        return $this->fetch('seo/sitemap');
68
+    }
69
+
70
+    /**
71
+     * 生成相应的搜索引擎sitemap
72
+     */
73
+    public function create($ver = 'xml')
74
+    {
75
+        if (empty($ver)) {
76
+            sitemap_all();
77
+        } else {
78
+            $fun_name = 'sitemap_'.$ver;
79
+            $fun_name();
80
+        }
81
+    }
82
+}

+ 969
- 0
application/admin/controller/Special.php View File

@@ -0,0 +1,969 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Page;
17
+use think\Db;
18
+use think\Config;
19
+
20
+class Special extends Base
21
+{
22
+    public $nid = 'special';
23
+    public $channeltype = '';
24
+
25
+    public function _initialize()
26
+    {
27
+        parent::_initialize();
28
+        $channeltype_list  = config('global.channeltype_list');
29
+        $this->channeltype = $channeltype_list[$this->nid];
30
+        empty($this->channeltype) && $this->channeltype = 7;
31
+        $this->assign('nid', $this->nid);
32
+        $this->assign('channeltype', $this->channeltype);
33
+
34
+        // 返回页面
35
+        $paramTypeid = input('param.typeid/d', 0);
36
+        $this->callback_url = url('Special/index', ['lang' => $this->admin_lang, 'typeid' => $paramTypeid]);
37
+        $this->assign('callback_url', $this->callback_url);
38
+    }
39
+
40
+    //专题列表
41
+    public function index()
42
+    {
43
+        $assign_data = $condition = [];
44
+
45
+        // 获取到所有GET参数
46
+        $param = input('param.');
47
+        $typeid = input('typeid/d', 0);
48
+
49
+        // 搜索、筛选查询条件处理
50
+        foreach (['keywords', 'typeid', 'flag', 'is_release','province_id','city_id','area_id'] as $key) {
51
+            if ($key == 'typeid' && empty($param['typeid'])) {
52
+                $typeids = Db::name('arctype')->where('current_channel', $this->channeltype)->column('id');
53
+                $condition['a.typeid'] = array('IN', $typeids);
54
+            }
55
+            if (isset($param[$key]) && $param[$key] !== '') {
56
+                if ($key == 'keywords') {
57
+                    $keywords = $param[$key];
58
+                    $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
59
+                } else if ($key == 'typeid') {
60
+                    $typeid = $param[$key];
61
+                    $hasRow = model('Arctype')->getHasChildren($typeid);
62
+                    $typeids = get_arr_column($hasRow, 'id');
63
+                    // 权限控制 by 小虎哥
64
+                    $admin_info = session('admin_info');
65
+                    if (0 < intval($admin_info['role_id'])) {
66
+                        $auth_role_info = $admin_info['auth_role_info'];
67
+                        if (!empty($typeid) && !empty($auth_role_info) && !empty($auth_role_info['permission']['arctype'])) {
68
+                            $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
69
+                        }
70
+                    }
71
+                    $condition['a.typeid'] = array('IN', $typeids);
72
+                } else if ($key == 'flag') {
73
+                    if ('is_release' == $param[$key]) {
74
+                        $condition['a.users_id'] = array('gt', 0);
75
+                    } else {
76
+                        $FlagNew = $param[$key];
77
+                        $condition['a.'.$param[$key]] = array('eq', 1);
78
+                    }
79
+                } else if (in_array($key, ['province_id','city_id','area_id'])) {
80
+                    if (!empty($param['area_id'])) {
81
+                        $condition['a.area_id'] = $param['area_id'];
82
+                    } else if (!empty($param['city_id'])) {
83
+                        $condition['a.city_id'] = $param['city_id'];
84
+                    } else if (!empty($param['province_id'])) {
85
+                        $condition['a.province_id'] = $param['province_id'];
86
+                    }
87
+                } else {
88
+                    $condition['a.'.$key] = array('eq', $param[$key]);
89
+                }
90
+            }
91
+        }
92
+
93
+        // 权限控制 by 小虎哥
94
+        $admin_info = session('admin_info');
95
+        if (0 < intval($admin_info['role_id'])) {
96
+            $auth_role_info = $admin_info['auth_role_info'];
97
+            if (!empty($auth_role_info) && isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']) {
98
+                $condition['a.admin_id'] = $admin_info['admin_id'];
99
+            }
100
+        }
101
+
102
+        // 时间检索条件
103
+        $begin = strtotime(input('add_time_begin'));
104
+        $end = strtotime(input('add_time_end'));
105
+        if ($begin > 0 && $end > 0) {
106
+            $condition['a.add_time'] = array('between', "$begin, $end");
107
+        } else if ($begin > 0) {
108
+            $condition['a.add_time'] = array('egt', $begin);
109
+        } else if ($end > 0) {
110
+            $condition['a.add_time'] = array('elt', $end);
111
+        }
112
+
113
+        // 必要条件
114
+        $condition['a.channel'] = array('eq', $this->channeltype);
115
+        $condition['a.lang'] = array('eq', $this->admin_lang);
116
+        $condition['a.is_del'] = array('eq', 0);
117
+        $conditionNew = "(a.users_id = 0 OR (a.users_id > 0 AND a.arcrank >= 0))";
118
+
119
+        // 自定义排序
120
+        $orderby = input('param.orderby/s');
121
+        $orderway = input('param.orderway/s');
122
+        if (!empty($orderby) && !empty($orderway)) {
123
+            $orderby = "a.{$orderby} {$orderway}, a.aid desc";
124
+        } else {
125
+            $orderby = "a.aid desc";
126
+        }
127
+
128
+        // 数据查询,搜索出主键ID的值
129
+        $SqlQuery = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->fetchSql()->count('aid');
130
+        $count = Db::name('sql_cache_table')->where(['sql_md5'=>md5($SqlQuery)])->getField('sql_result');
131
+        $count = ($count < 0) ? 0 : $count;
132
+        if (empty($count)) {
133
+            $count = Db::name('archives')->alias('a')->where($condition)->where($conditionNew)->count('aid');
134
+            /*添加查询执行语句到mysql缓存表*/
135
+            $SqlCacheTable = [
136
+                'sql_name' => '|special|' . $this->channeltype . '|',
137
+                'sql_result' => $count,
138
+                'sql_md5' => md5($SqlQuery),
139
+                'sql_query' => $SqlQuery,
140
+                'add_time' => getTime(),
141
+                'update_time' => getTime(),
142
+            ];
143
+            if (!empty($FlagNew)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $FlagNew . '|';
144
+            if (!empty($typeid)) $SqlCacheTable['sql_name'] = $SqlCacheTable['sql_name'] . $typeid . '|';
145
+            if (!empty($keywords)) $SqlCacheTable['sql_name'] = '|special|keywords|';
146
+            Db::name('sql_cache_table')->insertGetId($SqlCacheTable);
147
+            /*END*/
148
+        }
149
+
150
+        $Page = new Page($count, config('paginate.list_rows'));
151
+        $list = [];
152
+        if (!empty($count)) {
153
+            $limit = $count > config('paginate.list_rows') ? $Page->firstRow.','.$Page->listRows : $count;
154
+            $list = Db::name('archives')
155
+                ->field("a.aid")
156
+                ->alias('a')
157
+                ->where($condition)
158
+            	->where($conditionNew)
159
+                ->order($orderby)
160
+                ->limit($limit)
161
+                ->getAllWithIndex('aid');
162
+            if (!empty($list)) {
163
+                $aids = array_keys($list);
164
+                $fields = "b.*, a.*, a.aid as aid";
165
+                $row = Db::name('archives')
166
+                    ->field($fields)
167
+                    ->alias('a')
168
+                    ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
169
+                    ->where('a.aid', 'in', $aids)
170
+                    ->getAllWithIndex('aid');
171
+                foreach ($list as $key => $val) {
172
+                    $row[$val['aid']]['arcurl'] = get_arcurl($row[$val['aid']]);
173
+                    $row[$val['aid']]['litpic'] = handle_subdir_pic($row[$val['aid']]['litpic']);
174
+                    $list[$key] = $row[$val['aid']];
175
+                }
176
+            }
177
+        }
178
+        
179
+        $show = $Page->show();
180
+        $assign_data['page'] = $show;
181
+        $assign_data['list'] = $list;
182
+        $assign_data['pager'] = $Page;
183
+        $assign_data['typeid'] = $typeid;
184
+        $assign_data['tab'] = input('param.tab/d', 3);// 选项卡
185
+        $assign_data['seo_pseudo'] = tpCache('global.seo_pseudo');// 前台URL模式
186
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();// 文档属性
187
+        $assign_data['arctype_info'] = $typeid > 0 ? Db::name('arctype')->field('typename')->find($typeid) : [];// 当前栏目信息
188
+        $this->assign($assign_data);
189
+        return $this->fetch();
190
+    }
191
+
192
+    /**
193
+     * 添加
194
+     */
195
+    public function add()
196
+    {
197
+        $admin_info = session('admin_info');
198
+        $auth_role_info = $admin_info['auth_role_info'];
199
+        $this->assign('auth_role_info', $auth_role_info);
200
+        $this->assign('admin_info', $admin_info);
201
+        if (IS_POST) {
202
+            $post = input('post.');
203
+            model('Archives')->editor_auto_210607($post);
204
+            /* 处理TAG标签 */
205
+            if (!empty($post['tags_new'])) {
206
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
207
+                unset($post['tags_new']);
208
+            }
209
+            $post['tags'] = explode(',', $post['tags']);
210
+            $post['tags'] = array_unique($post['tags']);
211
+            $post['tags'] = implode(',', $post['tags']);
212
+            /* END */
213
+
214
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
215
+
216
+            // 根据标题自动提取相关的关键字
217
+            $seo_keywords = $post['seo_keywords'];
218
+            if (!empty($seo_keywords)) {
219
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
220
+            } else {
221
+                // $seo_keywords = get_split_word($post['title'], $content);
222
+            }
223
+
224
+            // 自动获取内容第一张图片作为封面图
225
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
226
+            $litpic = '';
227
+            if ($is_remote == 1) {
228
+                $litpic = $post['litpic_remote'];
229
+            } else {
230
+                $litpic = $post['litpic_local'];
231
+            }
232
+            if (empty($litpic)) {
233
+                $litpic = get_html_first_imgurl($content);
234
+            }
235
+            $post['litpic'] = $litpic;
236
+
237
+            /*是否有封面图*/
238
+            if (empty($post['litpic'])) {
239
+                $is_litpic = 0; // 无封面图
240
+            } else {
241
+                $is_litpic = 1; // 有封面图
242
+            }
243
+
244
+            // SEO描述
245
+            $seo_description = '';
246
+            if (empty($post['seo_description']) && !empty($content)) {
247
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
248
+            } else {
249
+                $seo_description = $post['seo_description'];
250
+            }
251
+
252
+            // 外部链接跳转
253
+            $jumplinks = '';
254
+            $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
255
+            if (intval($is_jump) > 0) {
256
+                $jumplinks = $post['jumplinks'];
257
+            }
258
+
259
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
260
+            if ($post['type_tempview'] == $post['tempview']) {
261
+                unset($post['type_tempview']);
262
+                unset($post['tempview']);
263
+            }
264
+
265
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
266
+            $htmlfilename = trim($post['htmlfilename']);
267
+            if (!empty($htmlfilename)) {
268
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
269
+                // $htmlfilename = strtolower($htmlfilename);
270
+                //判断是否存在相同的自定义文件名
271
+                $map = [
272
+                    'htmlfilename'  => $htmlfilename,
273
+                    'lang'  => $this->admin_lang,
274
+                ];
275
+                if (!empty($post['typeid'])) {
276
+                    $map['typeid'] = array('eq', $post['typeid']);
277
+                }
278
+                $filenameCount = Db::name('archives')->where($map)->count();
279
+                if (!empty($filenameCount)) {
280
+                    $this->error("同栏目下,自定义文件名已存在!");
281
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
282
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
283
+                }
284
+            } else {
285
+                // 处理外贸链接
286
+                if (is_dir('./weapp/Waimao/')) {
287
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
288
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'add', $this->globalConfig);
289
+                }
290
+            }
291
+            $post['htmlfilename'] = $htmlfilename;
292
+
293
+            //做自动通过审核判断
294
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
295
+                $post['arcrank'] = -1;
296
+            }
297
+
298
+            // 副栏目
299
+            if (isset($post['stypeid'])) {
300
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
301
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
302
+                $post['stypeid'] = trim($post['stypeid'], ',');
303
+                $post['stypeid'] = str_replace(",{$post['typeid']},", ',', ",{$post['stypeid']},");
304
+                $post['stypeid'] = trim($post['stypeid'], ',');
305
+            }
306
+            
307
+            // --存储数据
308
+            $newData = array(
309
+                'title'=> trim($post['title']),
310
+                'typeid'=> empty($post['typeid']) ? 0 : $post['typeid'],
311
+                'channel'   => $this->channeltype,
312
+                'is_b'      => empty($post['is_b']) ? 0 : $post['is_b'],
313
+                'is_head'      => empty($post['is_head']) ? 0 : $post['is_head'],
314
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
315
+                'is_recom'      => empty($post['is_recom']) ? 0 : $post['is_recom'],
316
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
317
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
318
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
319
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
320
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
321
+                'is_jump'     => $is_jump,
322
+                'is_litpic'     => $is_litpic,
323
+                'jumplinks' => $jumplinks,
324
+                'origin'      => empty($post['origin']) ? '网络' : $post['origin'],
325
+                'seo_keywords'     => $seo_keywords,
326
+                'seo_description'     => $seo_description,
327
+                'admin_id'  => session('admin_info.admin_id'),
328
+                'lang'  => $this->admin_lang,
329
+                'sort_order'    => 100,
330
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
331
+                'add_time'     => strtotime($post['add_time']),
332
+                'update_time'  => strtotime($post['add_time']),
333
+            );
334
+            $data = array_merge($post, $newData);
335
+
336
+            $aid          = Db::name('archives')->insertGetId($data);
337
+            $_POST['aid'] = $aid;
338
+            if ($aid) {
339
+                // ---------后置操作
340
+                model('Special')->afterSave($aid, $data, 'add');
341
+                // 添加查询执行语句到mysql缓存表
342
+                model('SqlCacheTable')->InsertSqlCacheTable();
343
+                // ---------end
344
+                adminLog('新增专题:'.$data['title']);
345
+
346
+                // 生成静态页面代码
347
+                $successData = [
348
+                    'aid'   => $aid,
349
+                    'tid'   => $post['typeid'],
350
+                ];
351
+                $this->success("操作成功!", null, $successData);
352
+                exit;
353
+            }
354
+
355
+            $this->error("操作失败!");
356
+            exit;
357
+        }
358
+
359
+        $typeid = input('param.typeid/d', 0);
360
+        $assign_data['typeid'] = $typeid; // 栏目ID
361
+
362
+        // 栏目信息
363
+        $arctypeInfo = Db::name('arctype')->find($typeid);
364
+
365
+        /*允许发布文档列表的栏目*/
366
+        $arctype_html = allow_release_arctype($typeid, array($this->channeltype));
367
+        $assign_data['arctype_html'] = $arctype_html;
368
+        /*--end*/
369
+
370
+        // 阅读权限
371
+        $arcrank_list = get_arcrank_list();
372
+        $assign_data['arcrank_list'] = $arcrank_list;
373
+
374
+        /*模板列表*/
375
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
376
+        $templateList = $archivesLogic->getTemplateList($this->nid);
377
+        $this->assign('templateList', $templateList);
378
+        /*--end*/
379
+
380
+        /*默认模板文件*/
381
+        $tempview = 'view_'.$this->nid.'.'.config('template.view_suffix');
382
+        !empty($arctypeInfo['tempview']) && $tempview = $arctypeInfo['tempview'];
383
+        $this->assign('tempview', $tempview);
384
+        /*--end*/
385
+
386
+        // URL模式
387
+        $tpcache = config('tpcache');
388
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
389
+        /*--end*/
390
+
391
+        /*节点允许发布文档列表的栏目*/
392
+        $allow_release_channel = config('global.allow_release_channel');
393
+        $key_tmp = array_search('7', $allow_release_channel);
394
+        if (is_numeric($key_tmp) && 0 <= $key_tmp) {
395
+            unset($allow_release_channel[$key_tmp]);
396
+        }
397
+        $node_select_html = allow_release_arctype(0, $allow_release_channel);
398
+        $assign_data['node_select_html'] = $node_select_html;
399
+        /*--end*/
400
+
401
+        /* 节点模型列表 */
402
+        $allow_release_channel = config('global.allow_release_channel');
403
+        $node_channeltype_list = \think\Cache::get('extra_global_channeltype');
404
+        foreach ($node_channeltype_list as $key => $val) {
405
+            if (!in_array($val['id'], $allow_release_channel)) {
406
+                unset($node_channeltype_list[$val['id']]);
407
+            }
408
+        }
409
+        unset($node_channeltype_list[7]);
410
+        $assign_data['node_channeltype_list'] = $node_channeltype_list;
411
+        /*--end*/
412
+
413
+        // 文档默认浏览量
414
+        $globalConfig = tpCache('global');
415
+        if (isset($globalConfig['other_arcclick']) && 0 <= $globalConfig['other_arcclick']) {
416
+            $arcclick_arr = explode("|", $globalConfig['other_arcclick']);
417
+            if (count($arcclick_arr) > 1) {
418
+                $assign_data['rand_arcclick'] = mt_rand($arcclick_arr[0], $arcclick_arr[1]);
419
+            } else {
420
+                $assign_data['rand_arcclick'] = intval($arcclick_arr[0]);
421
+            }
422
+        }else{
423
+            $arcclick_config['other_arcclick'] = '500|1000';
424
+            tpCache('other', $arcclick_config);
425
+            $assign_data['rand_arcclick'] = mt_rand(500, 1000);
426
+        }
427
+
428
+        /*文档属性*/
429
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
430
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
431
+        $assign_data['channelRow'] = $channelRow;
432
+
433
+        // 来源列表
434
+        $system_originlist = tpSetting('system.system_originlist');
435
+        $system_originlist = json_decode($system_originlist, true);
436
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
437
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
438
+        $assign_data['system_originlist_0'] = !empty($system_originlist) ? $system_originlist[0] : "";
439
+        // 多站点,当用站点域名访问后台,发布文档自动选择当前所属区域
440
+        model('Citysite')->auto_location_select($assign_data);
441
+        
442
+        $this->assign($assign_data);
443
+
444
+        return $this->fetch();
445
+    }
446
+
447
+    /**
448
+     * 编辑
449
+     */
450
+    public function edit()
451
+    {
452
+        $admin_info = session('admin_info');
453
+        $auth_role_info = $admin_info['auth_role_info'];
454
+        $this->assign('auth_role_info', $auth_role_info);
455
+        $this->assign('admin_info', $admin_info);
456
+
457
+        if (IS_POST) {
458
+            $post = input('post.');
459
+            model('Archives')->editor_auto_210607($post);
460
+            $post['aid'] = intval($post['aid']);
461
+
462
+            /* 处理TAG标签 */
463
+            if (!empty($post['tags_new'])) {
464
+                $post['tags'] = !empty($post['tags']) ? $post['tags'] . ',' . $post['tags_new'] : $post['tags_new'];
465
+                unset($post['tags_new']);
466
+            }
467
+            $post['tags'] = explode(',', $post['tags']);
468
+            $post['tags'] = array_unique($post['tags']);
469
+            $post['tags'] = implode(',', $post['tags']);
470
+            /* END */
471
+
472
+            $typeid = input('post.typeid/d', 0);
473
+            $content = empty($post['addonFieldExt']['content']) ? '' : htmlspecialchars_decode($post['addonFieldExt']['content']);
474
+
475
+            // 根据标题自动提取相关的关键字
476
+            $seo_keywords = $post['seo_keywords'];
477
+            if (!empty($seo_keywords)) {
478
+                $seo_keywords = str_replace(',', ',', $seo_keywords);
479
+            } else {
480
+                // $seo_keywords = get_split_word($post['title'], $content);
481
+            }
482
+
483
+            // 自动获取内容第一张图片作为封面图
484
+            $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
485
+            $litpic = '';
486
+            if ($is_remote == 1) {
487
+                $litpic = $post['litpic_remote'];
488
+            } else {
489
+                $litpic = $post['litpic_local'];
490
+            }
491
+            if (empty($litpic)) {
492
+                $litpic = get_html_first_imgurl($content);
493
+            }
494
+            $post['litpic'] = $litpic;
495
+
496
+            /*是否有封面图*/
497
+            if (empty($post['litpic'])) {
498
+                $is_litpic = 0; // 无封面图
499
+            } else {
500
+                $is_litpic = !empty($post['is_litpic']) ? $post['is_litpic'] : 0; // 有封面图
501
+            }
502
+
503
+            // 勾选后SEO描述将随正文内容更新
504
+            $basic_update_seo_description = empty($post['basic_update_seo_description']) ? 0 : 1;
505
+            if (is_language()) {
506
+                $langRow = \think\Db::name('language')->order('id asc')
507
+                    ->cache(true, EYOUCMS_CACHE_TIME, 'language')
508
+                    ->select();
509
+                foreach ($langRow as $key => $val) {
510
+                    tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description], $val['mark']);
511
+                }
512
+            } else {
513
+                tpCache('basic', ['basic_update_seo_description'=>$basic_update_seo_description]);
514
+            }
515
+            /*--end*/
516
+
517
+            // SEO描述
518
+            $seo_description = '';
519
+            if (!empty($basic_update_seo_description) || empty($post['seo_description'])) {
520
+                $seo_description = @msubstr(checkStrHtml($content), 0, config('global.arc_seo_description_length'), false);
521
+            } else {
522
+                $seo_description = $post['seo_description'];
523
+            }
524
+
525
+            // --外部链接
526
+            $jumplinks = '';
527
+            $is_jump = isset($post['is_jump']) ? $post['is_jump'] : 0;
528
+            if (intval($is_jump) > 0) {
529
+                $jumplinks = $post['jumplinks'];
530
+            }
531
+
532
+            // 模板文件,如果文档模板名与栏目指定的一致,默认就为空。让它跟随栏目的指定而变
533
+            if ($post['type_tempview'] == $post['tempview']) {
534
+                unset($post['type_tempview']);
535
+                unset($post['tempview']);
536
+            }
537
+
538
+            // 同步栏目切换模型之后的文档模型
539
+            $channel = Db::name('arctype')->where(['id'=>$typeid])->getField('current_channel');
540
+
541
+            //处理自定义文件名,仅由字母数字下划线和短横杆组成,大写强制转换为小写
542
+            $htmlfilename = trim($post['htmlfilename']);
543
+            if (!empty($htmlfilename)) {
544
+                $htmlfilename = preg_replace("/[^\x{4e00}-\x{9fa5}\w\-]+/u", "-", $htmlfilename);
545
+                // $htmlfilename = strtolower($htmlfilename);
546
+                //判断是否存在相同的自定义文件名
547
+                $map = [
548
+                    'aid'   => ['NEQ', $post['aid']],
549
+                    'htmlfilename'  => $htmlfilename,
550
+                    'lang'  => $this->admin_lang,
551
+                ];
552
+                if (!empty($post['typeid'])) {
553
+                    $map['typeid'] = array('eq', $post['typeid']);
554
+                }
555
+                $filenameCount = Db::name('archives')->where($map)->count();
556
+                if (!empty($filenameCount)) {
557
+                    $this->error("同栏目下,自定义文件名已存在!");
558
+                } else if (preg_match('/^(\d+)$/i', $htmlfilename)) {
559
+                    $this->error("自定义文件名不能纯数字,会与文档ID冲突!");
560
+                }
561
+            } else {
562
+                // 处理外贸链接
563
+                if (is_dir('./weapp/Waimao/')) {
564
+                    $waimaoLogic = new \weapp\Waimao\logic\WaimaoLogic;
565
+                    $waimaoLogic->get_new_htmlfilename($htmlfilename, $post, 'edit', $this->globalConfig);
566
+                }
567
+            }
568
+            $post['htmlfilename'] = $htmlfilename;
569
+
570
+            //做未通过审核文档不允许修改文档状态操作
571
+            if ($admin_info['role_id'] > 0 && $auth_role_info['check_oneself'] < 1) {
572
+                $old_archives_arcrank = Db::name('archives')->where(['aid' => $post['aid']])->getField("arcrank");
573
+                if ($old_archives_arcrank < 0) {
574
+                    unset($post['arcrank']);
575
+                }
576
+            }
577
+
578
+            // 副栏目
579
+            if (isset($post['stypeid'])) {
580
+                $post['stypeid'] = preg_replace('/([^\d\,\,]+)/i', ',', $post['stypeid']);
581
+                $post['stypeid'] = str_replace(',', ',', $post['stypeid']);
582
+                $post['stypeid'] = trim($post['stypeid'], ',');
583
+                $post['stypeid'] = str_replace(",{$typeid},", ',', ",{$post['stypeid']},");
584
+                $post['stypeid'] = trim($post['stypeid'], ',');
585
+            }
586
+
587
+            // --存储数据
588
+            $newData = array(
589
+                'title'=> trim($post['title']),
590
+                'typeid'=> $typeid,
591
+                'channel'   => $channel,
592
+                'is_b'      => empty($post['is_b']) ? 0 : $post['is_b'],
593
+                'is_head'      => empty($post['is_head']) ? 0 : $post['is_head'],
594
+                'is_special'      => empty($post['is_special']) ? 0 : $post['is_special'],
595
+                'is_recom'      => empty($post['is_recom']) ? 0 : $post['is_recom'],
596
+                'is_roll'      => empty($post['is_roll']) ? 0 : $post['is_roll'],
597
+                'is_slide'      => empty($post['is_slide']) ? 0 : $post['is_slide'],
598
+                'is_diyattr'      => empty($post['is_diyattr']) ? 0 : $post['is_diyattr'],
599
+                'editor_remote_img_local'=> empty($post['editor_remote_img_local']) ? 0 : $post['editor_remote_img_local'],
600
+                'editor_img_clear_link'  => empty($post['editor_img_clear_link']) ? 0 : $post['editor_img_clear_link'],
601
+                'is_jump'   => $is_jump,
602
+                'is_litpic'     => $is_litpic,
603
+                'jumplinks' => $jumplinks,
604
+                'seo_keywords'     => $seo_keywords,
605
+                'seo_description'     => $seo_description,
606
+                'crossed_price'     => empty($post['crossed_price']) ? 0 : floatval($post['crossed_price']),
607
+                'add_time'     => strtotime($post['add_time']),
608
+                'update_time'     => getTime(),
609
+            );
610
+            $data = array_merge($post, $newData);
611
+
612
+            $r = Db::name('archives')->where([
613
+                    'aid'   => $data['aid'],
614
+                    'lang'  => $this->admin_lang,
615
+                ])->update($data);
616
+            
617
+            if ($r) {
618
+                // ---------后置操作
619
+                model('Special')->afterSave($data['aid'], $data, 'edit');
620
+                // ---------end
621
+                adminLog('编辑专题:'.$data['title']);
622
+
623
+                // 生成静态页面代码
624
+                $successData = [
625
+                    'aid'       => $data['aid'],
626
+                    'tid'       => $typeid,
627
+                ];
628
+                $this->success("操作成功!", null, $successData);
629
+                exit;
630
+            }
631
+
632
+            $this->error("操作失败!");
633
+            exit;
634
+        }
635
+
636
+        $assign_data = array();
637
+
638
+        $id = input('id/d');
639
+        $info = model('Special')->getInfo($id, null, false);
640
+        if (empty($info)) {
641
+            $this->error('数据不存在,请联系管理员!');
642
+            exit;
643
+        }
644
+        /*兼容采集没有归属栏目的文档*/
645
+        if (empty($info['channel'])) {
646
+            $channelRow = Db::name('channeltype')->field('id as channel')
647
+                ->where('id',$this->channeltype)
648
+                ->find();
649
+            $info = array_merge($info, $channelRow);
650
+        }
651
+        /*--end*/
652
+        $typeid = $info['typeid'];
653
+        $assign_data['typeid'] = $typeid;
654
+        
655
+        // 副栏目
656
+        $stypeid_arr = [];
657
+        if (!empty($info['stypeid'])) {
658
+            $info['stypeid'] = trim($info['stypeid'], ',');
659
+            $stypeid_arr = Db::name('arctype')->field('id,typename')->where(['id'=>['IN', $info['stypeid']],'is_del'=>0])->select();
660
+        }
661
+        $assign_data['stypeid_arr'] = $stypeid_arr;
662
+
663
+        // 栏目信息
664
+        $arctypeInfo = Db::name('arctype')->find($typeid);
665
+
666
+        $info['channel'] = $arctypeInfo['current_channel'];
667
+        if (is_http_url($info['litpic'])) {
668
+            $info['is_remote'] = 1;
669
+            $info['litpic_remote'] = handle_subdir_pic($info['litpic']);
670
+        } else {
671
+            $info['is_remote'] = 0;
672
+            $info['litpic_local'] = handle_subdir_pic($info['litpic']);
673
+        }
674
+    
675
+        // SEO描述
676
+        // if (!empty($info['seo_description'])) {
677
+        //     $info['seo_description'] = @msubstr(checkStrHtml($info['seo_description']), 0, config('global.arc_seo_description_length'), false);
678
+        // }
679
+
680
+        $assign_data['field'] = $info;
681
+
682
+        /*允许发布文档列表的栏目,文档所在模型以栏目所在模型为主,兼容切换模型之后的数据编辑*/
683
+        $arctype_html = allow_release_arctype($typeid, array($info['channel']));
684
+        $assign_data['arctype_html'] = $arctype_html;
685
+        /*--end*/
686
+
687
+        // 阅读权限
688
+        $arcrank_list = get_arcrank_list();
689
+        $assign_data['arcrank_list'] = $arcrank_list;
690
+
691
+        /*模板列表*/
692
+        $archivesLogic = new \app\admin\logic\ArchivesLogic;
693
+        $templateList = $archivesLogic->getTemplateList($this->nid);
694
+        $this->assign('templateList', $templateList);
695
+        /*--end*/
696
+
697
+        /*默认模板文件*/
698
+        $tempview = $info['tempview'];
699
+        empty($tempview) && $tempview = $arctypeInfo['tempview'];
700
+        $this->assign('tempview', $tempview);
701
+        /*--end*/
702
+
703
+        // URL模式
704
+        $tpcache = config('tpcache');
705
+        $assign_data['seo_pseudo'] = !empty($tpcache['seo_pseudo']) ? $tpcache['seo_pseudo'] : 1;
706
+        /*--end*/
707
+
708
+        /*节点允许发布文档列表的栏目*/
709
+        $allow_release_channel = config('global.allow_release_channel');
710
+        $key_tmp = array_search('7', $allow_release_channel);
711
+        if (is_numeric($key_tmp) && 0 <= $key_tmp) {
712
+            unset($allow_release_channel[$key_tmp]);
713
+        }
714
+        $node_select_html = allow_release_arctype(0, $allow_release_channel);
715
+        $assign_data['node_select_html'] = $node_select_html;
716
+        /*--end*/
717
+
718
+        /* 节点模型列表 */
719
+        $allow_release_channel = config('global.allow_release_channel');
720
+        $node_channeltype_list = \think\Cache::get('extra_global_channeltype');
721
+        foreach ($node_channeltype_list as $key => $val) {
722
+            if (!in_array($val['id'], $allow_release_channel)) {
723
+                unset($node_channeltype_list[$val['id']]);
724
+            }
725
+        }
726
+        unset($node_channeltype_list[7]);
727
+        $assign_data['node_channeltype_list'] = $node_channeltype_list;
728
+        /*--end*/
729
+
730
+        /*节点数据*/
731
+        $specialNodeList = model('SpecialNode')->getList($id);
732
+        $aidlists = '';
733
+        foreach ($specialNodeList as $key => $value) {
734
+            $aidlists .= 0 === intval($key) ? $value['aidlist'] : ',' . $value['aidlist'];
735
+        }
736
+        if (!empty($aidlists)) {
737
+            $where = [
738
+                'aid' => ['IN', $aidlists]
739
+            ];
740
+            $archives = Db::name('archives')->field('aid, title')->where($where)->getAllWithIndex('aid');
741
+            foreach ($specialNodeList as $key => $value) {
742
+                $value['archivesList'] = [];
743
+                $aidlists = !empty($value['aidlist']) ? explode(',', $value['aidlist']) : [];
744
+                foreach ($aidlists as $value_1) {
745
+                    if (!empty($archives[$value_1])) array_push($value['archivesList'], $archives[$value_1]);
746
+                }
747
+                $value['htmllist'] = json_encode($value['archivesList']);
748
+                $specialNodeList[$key] = $value;
749
+            }
750
+        }
751
+        $assign_data['specialNodeList'] = $specialNodeList;
752
+        /*--end*/
753
+
754
+        /*文档属性*/
755
+        $assign_data['archives_flags'] = model('ArchivesFlag')->getList();
756
+        $channelRow = Db::name('channeltype')->where('id', $this->channeltype)->find();
757
+        $assign_data['channelRow'] = $channelRow;
758
+
759
+        // 来源列表
760
+        $system_originlist = tpSetting('system.system_originlist');
761
+        $system_originlist = json_decode($system_originlist, true);
762
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
763
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
764
+
765
+        $this->assign($assign_data);
766
+        return $this->fetch();
767
+    }
768
+    
769
+    /**
770
+     * 删除
771
+     */
772
+    public function del()
773
+    {
774
+        if (IS_POST) {
775
+            $archivesLogic = new \app\admin\logic\ArchivesLogic;
776
+            $archivesLogic->del([], 0, 'special');
777
+        }
778
+    }
779
+
780
+    /**
781
+     * 选择节点文档
782
+     * @return [type] [description]
783
+     */
784
+    public function ajax_node_archives_list()
785
+    {
786
+        $assign_data = array();
787
+        $condition = array();
788
+        // 获取到所有URL参数
789
+        $param = input('param.');
790
+        $typeid = input('param.typeid/d');
791
+        $channels = input('param.channel/s');
792
+
793
+        // 应用搜索条件
794
+        foreach (['keywords','typeid','channel'] as $key) {
795
+            if ($key == 'keywords' && !empty($param[$key])) {
796
+                $param[$key] = trim($param[$key]);
797
+                $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
798
+            } else if ($key == 'typeid' && !empty($param[$key])) {
799
+                $typeid = $param[$key];
800
+                $hasRow = model('Arctype')->getHasChildren($typeid);
801
+                $typeids = get_arr_column($hasRow, 'id');
802
+                /*权限控制 by 小虎哥*/
803
+                $admin_info = session('admin_info');
804
+                if (0 < intval($admin_info['role_id'])) {
805
+                    $auth_role_info = $admin_info['auth_role_info'];
806
+                    if(! empty($auth_role_info)){
807
+                        if(isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']){
808
+                            $condition['a.admin_id'] = $admin_info['admin_id'];
809
+                        }
810
+                        if(! empty($auth_role_info['permission']['arctype'])){
811
+                            if (!empty($typeid)) {
812
+                                $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
813
+                            }
814
+                        }
815
+                    }
816
+                }
817
+                /*--end*/
818
+                $condition['a.typeid'] = array('IN', $typeids);
819
+            } else if ($key == 'channel') {
820
+                if (empty($param[$key])) {
821
+                    $allow_release_channel = config('global.allow_release_channel');
822
+                    $key_tmp = array_search('7', $allow_release_channel);
823
+                    if (is_numeric($key_tmp) && 0 <= $key_tmp) {
824
+                        unset($allow_release_channel[$key_tmp]);
825
+                    }
826
+                    $param[$key] = implode(',', $allow_release_channel);
827
+                }
828
+                $condition['a.'.$key] = array('in', explode(',', $param[$key]));
829
+            } else if (!empty($param[$key])) {
830
+                $condition['a.'.$key] = array('eq', $param[$key]);
831
+            }
832
+        }
833
+
834
+        // 审核通过
835
+        $condition['a.arcrank'] = array('gt', -1);
836
+        /*多语言*/
837
+        $condition['a.lang'] = array('eq', $this->admin_lang);
838
+        /*回收站数据不显示*/
839
+        $condition['a.is_del'] = array('eq', 0);
840
+
841
+        /**
842
+         * 数据查询,搜索出主键ID的值
843
+         */
844
+        $count = Db::name('archives')->alias('a')->where($condition)->count('aid');// 查询满足要求的总记录数
845
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
846
+        $list = Db::name('archives')
847
+            ->field("a.aid")
848
+            ->alias('a')
849
+            ->where($condition)
850
+            ->order('a.sort_order asc, a.aid desc')
851
+            ->limit($Page->firstRow.','.$Page->listRows)
852
+            ->getAllWithIndex('aid');
853
+
854
+        /**
855
+         * 完善数据集信息
856
+         * 在数据量大的情况下,经过优化的搜索逻辑,先搜索出主键ID,再通过ID将其他信息补充完整;
857
+         */
858
+        if ($list) {
859
+            $aids = array_keys($list);
860
+            $fields = "b.*, a.*, a.aid as aid";
861
+            $row = Db::name('archives')
862
+                ->field($fields)
863
+                ->alias('a')
864
+                ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
865
+                ->where('a.aid', 'in', $aids)
866
+                ->getAllWithIndex('aid');
867
+            foreach ($list as $key => $val) {
868
+                $list[$key] = $row[$val['aid']];
869
+            }
870
+        }
871
+        $show = $Page->show(); // 分页显示输出
872
+        $assign_data['page'] = $show; // 赋值分页输出
873
+        $assign_data['list'] = $list; // 赋值数据集
874
+        $assign_data['pager'] = $Page; // 赋值分页对象
875
+
876
+        /*允许发布文档列表的栏目*/
877
+        $allow_release_channel = !empty($channels) ? explode(',', $channels) : config('global.allow_release_channel');
878
+        $key_tmp = array_search('7', $allow_release_channel);
879
+        if (is_numeric($key_tmp) && 0 <= $key_tmp) {
880
+            unset($allow_release_channel[$key_tmp]);
881
+        }
882
+        $assign_data['arctype_html'] = allow_release_arctype($typeid, $allow_release_channel);
883
+        /*--end*/
884
+
885
+        $this->assign($assign_data);
886
+        
887
+        return $this->fetch();
888
+    }
889
+    //帮助
890
+    public function help()
891
+    {
892
+        $system_originlist = tpSetting('system.system_originlist');
893
+        $system_originlist = json_decode($system_originlist, true);
894
+        $system_originlist = !empty($system_originlist) ? $system_originlist : [];
895
+        $assign_data['system_originlist_str'] = implode(PHP_EOL, $system_originlist);
896
+        $this->assign($assign_data);
897
+    
898
+        return $this->fetch();
899
+    }
900
+
901
+    /**
902
+     * 用于专题节点文档来源的逻辑
903
+     * @return [type] [description]
904
+     */
905
+    public function ajax_recordfile()
906
+    {
907
+        \think\Session::pause(); // 暂停session,防止session阻塞机制
908
+        if (IS_AJAX) {
909
+            $opt = input('param.opt/s');
910
+            $value = input('param.value/s');
911
+            $filename = ROOT_PATH . 'data/conf/nodeaids_1619141574.txt';
912
+            if ('set' == $opt) {
913
+                $redata = $this->writeSpecialaidsFile($value);
914
+                if (true !== $redata) {
915
+                    $this->error($redata);
916
+                }
917
+                $this->success('写入成功!');
918
+            }
919
+            else if ('get' == $opt) {
920
+                $nodeaids = $this->readSpecialaidsFile();
921
+                $list = [];
922
+                if (!empty($nodeaids)) {
923
+                    $aids = explode(',', $nodeaids);
924
+                    $list = Db::name('archives')->field('aid,title')->where(['aid'=>['IN', $aids]])->orderRaw("FIND_IN_SET(aid, '{$nodeaids}')")->select();
925
+                }
926
+                $this->success('读取成功!', null, ['nodeaids'=>$nodeaids,'list'=>$list]);
927
+            }
928
+        }
929
+    }
930
+
931
+    /**
932
+     * 读取节点文档列表的aid文件 - 应用于专题发布、编辑的文档
933
+     * @return [type] [description]
934
+     */
935
+    private function readSpecialaidsFile()
936
+    {
937
+        $node_aids = '';
938
+        $filename = ROOT_PATH . 'data/conf/nodeaids_1619141574.txt';
939
+        if (file_exists($filename)) {
940
+            $len     = filesize($filename);
941
+            if (!empty($len) && $len > 0) {
942
+                $fp      = fopen($filename, 'r');
943
+                $node_aids = fread($fp, $len);
944
+                fclose($fp);
945
+                $node_aids = $node_aids ? $node_aids : '';
946
+            }
947
+        }
948
+        return $node_aids;
949
+    }
950
+
951
+    /**
952
+     * 写入节点文档列表的aid文件 - 应用于专题发布、编辑的文档
953
+     * @return [type] [description]
954
+     */
955
+    private function writeSpecialaidsFile($value = '')
956
+    {
957
+        $filename = ROOT_PATH . 'data/conf/nodeaids_1619141574.txt';
958
+        if (!file_exists($filename)) tp_mkdir(dirname($filename));
959
+        $fp = fopen($filename, "w+");
960
+        if (empty($fp)) {
961
+            return "请设置" . $filename . "的权限为744";
962
+        } else {
963
+            if (fwrite($fp, $value)) {
964
+                fclose($fp);
965
+            }
966
+        }
967
+        return true;
968
+    }
969
+}

+ 293
- 0
application/admin/controller/Statistics.php View File

@@ -0,0 +1,293 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 易而优团队 by 陈风任 <491085389@qq.com>
11
+ * Date: 2019-11-21 
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use think\Db;
16
+use think\Config;
17
+use app\admin\logic\ShopLogic;
18
+
19
+// 数据统计
20
+class Statistics extends Base {
21
+
22
+    public $ShopLogic;
23
+    public $UsersConfigData = [];
24
+
25
+    public function _initialize() {
26
+        parent::_initialize();
27
+        $this->language_access(); // 多语言功能操作权限
28
+
29
+        // 会员中心配置信息
30
+        $this->UsersConfigData = getUsersConfigData('all');
31
+        $this->assign('userConfig',$this->UsersConfigData);
32
+        
33
+        $this->ShopLogic = new ShopLogic;
34
+    }
35
+    
36
+    /**
37
+     * 数据表列表
38
+     */
39
+    public function index()
40
+    {
41
+        // 列出营销功能里已使用的模块
42
+        $marketFunc = $this->ShopLogic->marketLogic();
43
+        $this->assign('marketFunc', $marketFunc);
44
+
45
+        // 近七日成交量成交额折线图数据
46
+        $LineChartData = $this->GetLineChartData();
47
+        $this->assign('DealNum', $LineChartData['DealNum']);
48
+        $this->assign('DealAmount', $LineChartData['DealAmount']);
49
+
50
+        // 起始时间
51
+        $StartTime = $this->GetTime(6);
52
+        $EndTime = getTime();
53
+        $this->assign('StartTime', $StartTime);
54
+        $this->assign('EndTime', $EndTime);
55
+        // 数据统计
56
+        $CycletData = $this->GetTimeCycletData($StartTime, $EndTime);
57
+        $this->assign('CycletData', $CycletData);
58
+
59
+        // 商品销售榜
60
+        $OrderSalesList = $this->GetOrderSalesList();
61
+        $this->assign('OrderSalesList', $OrderSalesList);
62
+
63
+        // 用户消费榜
64
+        $UserConsumption = $this->GetUserConsumption();
65
+        $this->assign('UserConsumption', $UserConsumption);
66
+
67
+        return $this->fetch();
68
+    }
69
+
70
+    // 用户消费榜
71
+    private function GetUserConsumption()
72
+    {
73
+        $where = [
74
+            'order_status' => ['IN', [1, 2, 3]]
75
+        ];
76
+        $Return = Db::name('shop_order')->field('users_id, sum(order_total_amount+shipping_fee) as amount')->where($where)->group('users_id')->select();
77
+        $users_id = get_arr_column($Return, 'users_id');
78
+        $Return   = convert_arr_key($Return, 'users_id');
79
+
80
+        $UsersData = Db::name('users')->field('users_id, username, nickname')->select();
81
+        foreach ($UsersData as $key => $value) {
82
+            $UsersData[$key]['amount'] = !empty($Return[$value['users_id']]['amount']) ? $Return[$value['users_id']]['amount'] : 0;
83
+            $UsersData[$key]['nickname'] = !empty($UsersData[$key]['nickname']) ? $UsersData[$key]['nickname'] : $UsersData[$key]['username'];
84
+        }
85
+
86
+        // 以消费金额排序
87
+        array_multisort(get_arr_column($UsersData, 'amount'), SORT_DESC, $UsersData);
88
+        // 读取前十数据
89
+        $UsersData = array_slice($UsersData, 0, 10);
90
+
91
+        return $UsersData;
92
+    }
93
+
94
+    // 商品销售榜
95
+    private function GetOrderSalesList()
96
+    {
97
+        // 查询销量最高的前十个商品
98
+        $field_0 = 'aid, title, sales_num';
99
+        $where_0 = [
100
+            'typeid' => ['IN', Db::name('arctype')->where('current_channel', 2)->column('id')],
101
+            'channel' => 2,
102
+        ];
103
+        $Archives = Db::name('archives')->field($field_0)->where($where_0)->limit(10)->order('sales_num desc')->select();
104
+
105
+        // 统计单个商品销售总额
106
+        $where_1 = [
107
+            'a.product_id' => ['IN', get_arr_column($Archives, 'aid')],
108
+            'b.order_status' => ['IN', [1, 2, 3]],
109
+        ];
110
+        $Price = Db::name('shop_order_details')->alias('a')
111
+            ->field('a.product_id, sum(a.product_price*a.num) as price, count(a.details_id) as sales_num')
112
+            ->join('__SHOP_ORDER__ b', 'a.order_id = b.order_id', 'LEFT')
113
+            ->where($where_1)
114
+            ->group('product_id')
115
+            ->select();
116
+            
117
+        // 数据处理并返回
118
+        $Price = convert_arr_key($Price, 'product_id');
119
+        $Archives = convert_arr_key($Archives, 'aid');
120
+        $ArchivesNew = get_archives_data($Archives, 'aid');
121
+        foreach ($Archives as $key => $value) {
122
+            $Archives[$key]['arcurl'] = get_arcurl($ArchivesNew[$key]);
123
+            $Archives[$key]['title'] = @msubstr($value['title'], 0, 25, '...');
124
+            $Archives[$key]['sales_amount'] = !empty($Price[$key]['price']) ? $Price[$key]['price'] : 0;
125
+            $Archives[$key]['sales_num'] = !empty($Price[$key]['sales_num']) ? $Price[$key]['sales_num'] : 0;
126
+        }
127
+        return $Archives;
128
+    }
129
+
130
+    // 获取时间周期内的指定数据
131
+    public function GetTimeCycletData($Start = null, $End = null)
132
+    {
133
+        $param = input('param.');
134
+        if (!empty($param['Year']) && 0 != $param['Year']) {
135
+            $param['Start'] = strtotime("-0 year -{$param['Year']} month -0 day");
136
+            $param['End']   = getTime();
137
+        } else {
138
+            if (empty($Start) || empty($End)) {
139
+                $param['Start'] = strtotime($param['StartNew']);
140
+                $param['End']   = strtotime($param['EndNew']);
141
+            } else {
142
+                $param = [
143
+                    'Start' => $Start,
144
+                    'End'   => $End,
145
+                ];
146
+            }
147
+        }
148
+
149
+        // 会员查询条件
150
+        $Uwhere = [
151
+            'reg_time' => ['between', [$param['Start'], $param['End']]]
152
+        ];
153
+
154
+        // 商品查询条件
155
+        $Awhere = [
156
+            'typeid' => ['IN', Db::name('arctype')->where('current_channel', 2)->column('id')],
157
+            'channel'  => 2,
158
+            'add_time' => ['between', [$param['Start'], $param['End']]]
159
+        ];
160
+
161
+        // 商品查询条件
162
+        $Swhere = [
163
+            'add_time' => ['between', [$param['Start'], $param['End']]]
164
+        ];
165
+
166
+        // 订单查询条件
167
+        $Owhere = [
168
+            'order_status' => ['IN', [1, 2, 3]],
169
+            'add_time' => ['between', [$param['Start'], $param['End']]]
170
+        ];
171
+        // 查询订单数据
172
+        $Result = $this->GetTimeWhereData($Owhere);
173
+
174
+        // 充值查询条件
175
+        $Mwhere = [
176
+            'cause' => Config::get('global.pay_cause_type_arr')[1],
177
+            'cause_type' => 1,
178
+            'status' => 3,
179
+            'add_time' => ['between', [$param['Start'], $param['End']]]
180
+        ];
181
+        
182
+        $Return = [
183
+            // 会员人数
184
+            'UsersNum' => Db::name('users')->where($Uwhere)->count(),
185
+            // 付款订单数
186
+            'PayOrderNum' => $Result['deal_num'],
187
+            // 订单销售额
188
+            'OrderSales' => $Result['deal_amount'],
189
+            // 商品数
190
+            'ProductNum' => Db::name('archives')->where($Awhere)->count(),
191
+            // 消费人数
192
+            'OrderUsersNum' => Db::name('shop_order')->where($Swhere)->group('users_id')->count(),
193
+            // 充值金额
194
+            'UsersRecharge' => Db::name('users_money')->where($Mwhere)->sum('money'),
195
+            // 返回查询时间
196
+            'Start' => date("Y-m-d H:i:s", $param['Start']),
197
+            'End' => date("Y-m-d H:i:s", $param['End'])
198
+        ];
199
+
200
+        if (IS_AJAX_POST) {
201
+            $this->success('查询成功!', null, $Return);
202
+        } else {
203
+            return $Return;
204
+        }
205
+    }
206
+
207
+    // 近七日成交量成交额折线图数据    
208
+    private function GetLineChartData()
209
+    {
210
+        /*七日内每日起始结束时间戳*/
211
+        $Time = [
212
+            // 当天
213
+            'ToDaysStart' => strtotime(date("Y-m-d"),time()),
214
+            'ToDaysEnd' => getTime(),
215
+            // 昨天
216
+            'YesterDaysStart' => $this->GetTime(1),
217
+            'YesterDaysEnd' => $this->GetTime(1) + 86399,
218
+            // 前天
219
+            'AgoDaysStart' => $this->GetTime(2),
220
+            'AgoDaysEnd' => $this->GetTime(2) + 86399,
221
+            // 三天前
222
+            'ThreeDaysAgoStart' => $this->GetTime(3),
223
+            'ThreeDaysAgoEnd' => $this->GetTime(3) + 86399,
224
+            // 四天前
225
+            'FourDaysAgoStart' => $this->GetTime(4),
226
+            'FourDaysAgoEnd' => $this->GetTime(4) + 86399,
227
+            // 五天前
228
+            'FiveDaysAgoStart' => $this->GetTime(5),
229
+            'FiveDaysAgoEnd' => $this->GetTime(5) + 86399,
230
+            // 六天前
231
+            'SixDaysAgoStart' => $this->GetTime(6),
232
+            'SixDaysAgoEnd' => $this->GetTime(6) + 86399,
233
+        ];
234
+        /* END */
235
+
236
+        $where['order_status'] = ['IN', [1, 2, 3]];
237
+        // 六天前
238
+        $where['add_time']  = ['between', [$Time['SixDaysAgoStart'], $Time['SixDaysAgoEnd']]];
239
+        $Six = $this->GetTimeWhereData($where);
240
+        $Six['deal_amount'] = !empty($Six['deal_amount']) ? $Six['deal_amount'] : 0;
241
+        // 五天前
242
+        $where['add_time']  = ['between', [$Time['FiveDaysAgoStart'], $Time['FiveDaysAgoEnd']]];
243
+        $Five = $this->GetTimeWhereData($where);
244
+        $Five['deal_amount'] = !empty($Five['deal_amount']) ? $Five['deal_amount'] : 0;
245
+        // 四天前
246
+        $where['add_time']  = ['between', [$Time['FourDaysAgoStart'], $Time['FourDaysAgoEnd']]];
247
+        $Four = $this->GetTimeWhereData($where);
248
+        $Four['deal_amount'] = !empty($Four['deal_amount']) ? $Four['deal_amount'] : 0;
249
+        // 三天前
250
+        $where['add_time']  = ['between', [$Time['ThreeDaysAgoStart'], $Time['ThreeDaysAgoEnd']]];
251
+        $Three = $this->GetTimeWhereData($where);
252
+        $Three['deal_amount'] = !empty($Three['deal_amount']) ? $Three['deal_amount'] : 0;
253
+        // 前天
254
+        $where['add_time']  = ['between', [$Time['AgoDaysStart'], $Time['AgoDaysEnd']]];
255
+        $Ago = $this->GetTimeWhereData($where);
256
+        $Ago['deal_amount'] = !empty($Ago['deal_amount']) ? $Ago['deal_amount'] : 0;
257
+        // 昨天
258
+        $where['add_time']  = ['between', [$Time['YesterDaysStart'], $Time['YesterDaysEnd']]];
259
+        $Yester = $this->GetTimeWhereData($where);
260
+        $Yester['deal_amount'] = !empty($Yester['deal_amount']) ? $Yester['deal_amount'] : 0;
261
+        // 当天
262
+        $where['add_time']  = ['between', [$Time['ToDaysStart'], $Time['ToDaysEnd']]];
263
+        $ToDays = $this->GetTimeWhereData($where);
264
+        $ToDays['deal_amount'] = !empty($ToDays['deal_amount']) ? $ToDays['deal_amount'] : 0;
265
+
266
+        $Return = [
267
+            'DealAmount' => [$Six['deal_amount'], $Five['deal_amount'], $Four['deal_amount'], $Three['deal_amount'], $Ago['deal_amount'], $Yester['deal_amount'], $ToDays['deal_amount']],
268
+
269
+            'DealNum' => [$Six['deal_num'], $Five['deal_num'], $Four['deal_num'], $Three['deal_num'], $Ago['deal_num'], $Yester['deal_num'], $ToDays['deal_num']]
270
+        ];
271
+
272
+        return $Return;
273
+    }
274
+
275
+    // 获取指定日期下的数据
276
+    private function GetTimeWhereData($where = [])
277
+    {
278
+        $field = 'sum(order_total_amount+shipping_fee) as deal_amount, count(users_id) as deal_num';
279
+        $Return = Db::name('shop_order')->field($field)->where($where)->select();
280
+
281
+        $Return[0]['deal_amount'] = $Return[0]['deal_amount'] ? $Return[0]['deal_amount'] : 0;
282
+        $Return[0]['deal_num'] = $Return[0]['deal_num'] ? $Return[0]['deal_num'] : 0;
283
+        return $Return[0];
284
+    }
285
+
286
+    // 获取指定日期时间戳
287
+    private function GetTime($num = null)
288
+    {
289
+        $time = strtotime(date("Y-m-d", strtotime("-{$num} day")));
290
+        return $time;
291
+    }
292
+
293
+}

+ 2125
- 0
application/admin/controller/System.php
File diff suppressed because it is too large
View File


+ 653
- 0
application/admin/controller/Tags.php View File

@@ -0,0 +1,653 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class Tags extends Base
21
+{
22
+    public function index()
23
+    {
24
+        $list = array();
25
+        $param = input('param.');
26
+        $keywords = input('keywords/s');
27
+        $keywords = trim($keywords);
28
+        $condition = [];
29
+        // 应用搜索条件
30
+        foreach (['keywords'] as $key) {
31
+            if (isset($param[$key]) && $param[$key] !== '') {
32
+                if ($key == 'keywords') {
33
+                    $condition['tag'] = array('LIKE', "%{$keywords}%");
34
+                } else {
35
+                    $condition[$key] = array('eq', trim($param[$key]));
36
+                }
37
+            }
38
+        }
39
+        $condition['lang'] = array('eq', $this->admin_lang);
40
+
41
+        $tagsM =  Db::name('tagindex');
42
+        $count = $tagsM->where($condition)->count('id');
43
+        $Page = $pager = new Page($count, config('paginate.list_rows'));
44
+        $show = $Page->show();
45
+        $this->assign('page', $show);
46
+        $this->assign('pager', $pager);
47
+
48
+        // 查询ID数组,用于纠正本页TAG文档书
49
+        $IndexID = $tagsM->where($condition)->order('id desc')->limit($Page->firstRow.','.$Page->listRows)->column('id');
50
+
51
+        // 纠正tags标签的文档数
52
+        $this->correct($IndexID);
53
+    
54
+        $list = $tagsM->where($condition)->order('id desc')->limit($Page->firstRow.','.$Page->listRows)->select();
55
+        $this->assign('list', $list);
56
+
57
+        $source = input('param.source/s');
58
+        $this->assign('source', $source);
59
+        return $this->fetch();
60
+    }
61
+ 
62
+    public function tag_list()
63
+    {
64
+        $condition['lang'] = array('eq', $this->admin_lang);
65
+        $tagsM =  Db::name('tagindex');
66
+        $count = $tagsM->where($condition)->count('id');
67
+        $Page = $pager = new Page($count, 100);
68
+        $show = $Page->show();
69
+        $this->assign('page', $show);
70
+        $this->assign('pager', $pager);
71
+
72
+        // 查询ID数组,用于纠正本页TAG文档书
73
+        $IndexID = $tagsM->where($condition)->order($order)->limit($Page->firstRow.','.$Page->listRows)->column('id');
74
+
75
+        // 纠正tags标签的文档数
76
+        $this->correct($IndexID);
77
+
78
+        $order = 'total desc, id desc, monthcc desc, weekcc desc';
79
+        $list = $tagsM->where($condition)->order($order)->limit($Page->firstRow . ',' . $Page->listRows)->select();
80
+        
81
+        $this->assign('list', $list);
82
+        return $this->fetch();
83
+    }
84
+
85
+    public function edit()
86
+    {
87
+        if (IS_POST) {
88
+            $post = input('post.');
89
+            if (!empty($post['id'])) {
90
+                $post['id'] = intval($post['id']);
91
+                $tag = !empty($post['tag_tag']) ? trim($post['tag_tag']) : '';
92
+                if (empty($tag)) {
93
+                    $this->error('标签名称不能为空!');
94
+                } else {
95
+                    $row = Db::name('tagindex')->where([
96
+                            'tag'   => $tag,
97
+                            'id'    => ['NEQ', $post['id']],
98
+                            'lang'  => $this->admin_lang,
99
+                        ])->find();
100
+                    if (!empty($row)) {
101
+                        $this->error('标签名称已存在,请更改!');
102
+                    }
103
+                }
104
+
105
+                $is_remote = !empty($post['is_remote']) ? $post['is_remote'] : 0;
106
+                $litpic = '';
107
+                if ($is_remote == 1) {
108
+                    $litpic = $post['litpic_remote'];
109
+                } else {
110
+                    $litpic = $post['litpic_local'];
111
+                }
112
+                
113
+                $updata = [
114
+                    'tag' => $tag,
115
+                    'litpic' => $litpic,
116
+                    'seo_title' => !empty($post['tag_seo_title']) ? trim($post['tag_seo_title']) : '',
117
+                    'seo_keywords' => !empty($post['tag_seo_keywords']) ? trim($post['tag_seo_keywords']) : '',
118
+                    'seo_description' => !empty($post['tag_seo_description']) ? trim($post['tag_seo_description']) : '',
119
+                    'sort_order' => !empty($post['tag_sort_order']) ? trim($post['tag_sort_order']) : '100',
120
+                    'update_time' => getTime(),
121
+                ];
122
+                $ResultID = Db::name('tagindex')->where('id', $post['id'])->update($updata);
123
+                if (false !== $ResultID) {
124
+                    if (trim($post['tag_tag']) != trim($post['tag_tagold'])) {
125
+                        Db::name('taglist')->where([
126
+                                'tid'   => $post['id'],
127
+                            ])->update([
128
+                                'tag'   => trim($post['tag_tag']),
129
+                                'update_time'   => getTime(),
130
+                            ]);
131
+                        \think\Cache::clear('taglist');
132
+                    }
133
+                    $this->success('操作成功');
134
+                }
135
+            }
136
+            $this->error('操作失败');
137
+        }
138
+
139
+        $id = input('id/d');
140
+        $Result = Db::name('tagindex')->where('id', $id)->find();
141
+        if (empty($Result)) $this->error('操作异常');
142
+        if (is_http_url($Result['litpic'])) {
143
+            $Result['is_remote'] = 1;
144
+            $Result['litpic_remote'] = handle_subdir_pic($Result['litpic']);
145
+        } else {
146
+            $Result['is_remote'] = 0;
147
+            $Result['litpic_local'] = handle_subdir_pic($Result['litpic']);
148
+        }
149
+        $this->assign('tag', $Result);
150
+
151
+        $this->assign('backurl', url('Tags/index'));
152
+        return $this->fetch();
153
+    }
154
+
155
+    public function del()
156
+    {
157
+        if (IS_POST) {
158
+            $id_arr = input('del_id/a');
159
+            $id_arr = eyIntval($id_arr);
160
+            if(!empty($id_arr)){
161
+                $result = Db::name('tagindex')->field('tag')
162
+                    ->where([
163
+                        'id'    => ['IN', $id_arr],
164
+                        'lang'  => $this->admin_lang,
165
+                    ])->select();
166
+                $title_list = get_arr_column($result, 'tag');
167
+
168
+                $r = Db::name('tagindex')->where([
169
+                        'id'    => ['IN', $id_arr],
170
+                        'lang'  => $this->admin_lang,
171
+                    ])->delete();
172
+                if($r){
173
+                    Db::name('taglist')->where([
174
+                        'tid'    => ['IN', $id_arr],
175
+                        'lang'  => $this->admin_lang,
176
+                    ])->delete();
177
+                    \think\Cache::clear('taglist');
178
+                    adminLog('删除Tags标签:'.implode(',', $title_list));
179
+                    $this->success('删除成功');
180
+                }else{
181
+                    $this->error('删除失败');
182
+                }
183
+            } else {
184
+                $this->error('参数有误');
185
+            }
186
+        }
187
+        $this->error('非法访问');
188
+    }
189
+    
190
+    public function clearall()
191
+    {
192
+        $r = Db::name('tagindex')->where([
193
+                'lang'  => $this->admin_lang,
194
+            ])->delete();
195
+        if(false !== $r){
196
+            Db::name('taglist')->where([
197
+                'lang'  => $this->admin_lang,
198
+            ])->delete();
199
+            \think\Cache::clear('taglist');
200
+            adminLog('清空Tags标签');
201
+            $this->success('操作成功');
202
+        }else{
203
+            $this->error('操作失败');
204
+        }
205
+    }
206
+
207
+    /**
208
+     * 纠正tags文档数
209
+     */
210
+    private function correct($IndexID = [])
211
+    {
212
+        if (!empty($IndexID)) {
213
+            $where = [
214
+                'tid' => ['IN', $IndexID],
215
+                'lang' => $this->admin_lang
216
+            ];
217
+            $taglistRow = Db::name('taglist')->field('count(tid) as total, tid')
218
+                ->where($where)
219
+                ->group('tid')
220
+                ->getAllWithIndex('tid');
221
+            $updateData = [];
222
+            $weekup = getTime();
223
+            foreach ($taglistRow as $key => $val) {
224
+                $updateData[] = [
225
+                    'id'    => $val['tid'],
226
+                    'total' => $val['total'],
227
+                    'weekup'    => $weekup,
228
+                ];
229
+            }
230
+            if (!empty($updateData)) {
231
+                $r = model('Tagindex')->saveAll($updateData);
232
+                if (false !== $r) {
233
+                    // Db::name('tagindex')->where(['weekup'=>['lt', $weekup],'lang'=>$this->admin_lang])->delete();
234
+                }
235
+            }
236
+        }
237
+    }
238
+
239
+    /**
240
+     * 获取常用标签列表
241
+     */
242
+    public function get_common_list()
243
+    {
244
+        if (IS_AJAX) {
245
+            $tags = input('tags/s');
246
+            $type = input('type/d');
247
+            if (!empty($tags)){
248
+                $tagsArr = explode(',',$tags);
249
+                $tags  = trim(end($tagsArr));
250
+            }
251
+
252
+            /*发布最新文档的tag里前3个*/
253
+            $newTagList = [];
254
+            $newtids = [];
255
+            if (empty($tags)){
256
+                $taglistRow = Db::name('taglist')->field('tid,tag')->where(['lang'=>$this->admin_lang])->order('aid desc')->limit(20)->select();
257
+                foreach ($taglistRow as $key => $val) {
258
+                    if (3 <= count($newTagList)) {
259
+                        break;
260
+                    }
261
+                    if (in_array($val['tid'], $newtids)) {
262
+                        continue;
263
+                    }
264
+                    array_push($newTagList, $val);
265
+                    array_push($newtids, $val['tid']);
266
+                }
267
+            }
268
+            $list = $newTagList;
269
+            /*end*/
270
+
271
+            /*常用标签*/
272
+            $where = [];
273
+            $where['is_common'] = 1;
274
+            !empty($newtids) && $where['id'] = ['NOTIN', $newtids];
275
+            $where['lang'] = $this->admin_lang;
276
+            if (!empty($tags)){
277
+                $where['tag'] = ['like','%'.$tags."%"];
278
+            }
279
+            $num = 20 - count($list);
280
+            $row = Db::name('tagindex')->field('id as tid,tag')->where($where)
281
+                ->order('total desc, id desc')
282
+                ->limit($num)
283
+                ->select();
284
+            if (is_array($list) && is_array($row)) {
285
+                $list = array_merge($list, $row);
286
+            }
287
+            /*end*/
288
+
289
+            // 不够数量进行补充
290
+            $surplusNum = $num - count($list);
291
+            if (0 < $surplusNum) {
292
+                $ids = get_arr_column($list, 'tid');
293
+                $condition['lang'] = $this->admin_lang;
294
+                $condition['id'] = ['NOT IN', $ids];
295
+                if (!empty($tags)){
296
+                    $condition['tag'] = ['like','%'.$tags."%"];
297
+                }
298
+                $row2 = Db::name('tagindex')->field('id as tid,tag')->where($condition)
299
+                    ->order('total desc, id desc')
300
+                    ->limit($surplusNum)
301
+                    ->select();
302
+                if (is_array($list) && is_array($row2)) {
303
+                    $list = array_merge($list, $row2);
304
+                }
305
+            }
306
+            /*end*/
307
+
308
+            $html = "";
309
+            $data = [];
310
+            if (!empty($list)) {
311
+                $tags = input('param.tags/s');
312
+                $tags = str_replace(',', ',', $tags);
313
+                $tagArr = explode(',', $tags);
314
+                foreach ($tagArr as $key => $val) {
315
+                    $tagArr[$key] = trim($val);
316
+                }
317
+
318
+                foreach ($list as $_k1 => $_v1) {
319
+                    if (!empty($type)){
320
+                        if (in_array($_v1['tag'], $tagArr)) {
321
+                            $html .= "<a class='cur' href='javascript:void(0);' onclick='selectArchivesTagInput(this);'>{$_v1['tag']}</a>";
322
+                        } else {
323
+                            $html .= "<a href='javascript:void(0);' onclick='selectArchivesTagInput(this);'>{$_v1['tag']}</a>";
324
+                        }
325
+                    }else{
326
+                        if (in_array($_v1['tag'], $tagArr)) {
327
+                            $html .= "<a class='cur' href='javascript:void(0);' onclick='selectArchivesTag(this);'>{$_v1['tag']}</a>";
328
+                        } else {
329
+                            $html .= "<a href='javascript:void(0);' onclick='selectArchivesTag(this);'>{$_v1['tag']}</a>";
330
+                        }
331
+                    }
332
+                }
333
+            }
334
+
335
+            $is_click = input('param.is_click/d');
336
+            if (!empty($is_click)) {
337
+                if (empty($html)) {
338
+                    $html .= "没有找到记录";
339
+                }
340
+                // $html .= "<a href='javascript:void(0);' onclick='tags_list_1610411887(this);' style='float: right;'>[设置]</a>";
341
+            }
342
+            $data['html']   = $html;
343
+
344
+            if (!empty($type) && empty($tags)){
345
+                $data = [];
346
+            }
347
+
348
+            $this->success('请求成功', null, $data);
349
+        }
350
+        $this->error('请求失败');
351
+    }
352
+
353
+    public function batch_add()
354
+    {
355
+        if (IS_POST) {
356
+            $post = input('post.');
357
+
358
+            $tags = trim($post['tags']);
359
+            if (empty($tags)) {
360
+                $this->error('Tag列表不能为空!');
361
+            }
362
+
363
+            $tagsArr = explode("\r\n", $tags);
364
+            $tagsArr = array_filter($tagsArr);//去除数组空值
365
+            $tagsArr = array_unique($tagsArr); //去重
366
+            foreach ($tagsArr as $key => $val) {
367
+                $tagsArr[$key] = trim($val);
368
+            }
369
+
370
+            $addData = [];
371
+            $tagsList = Db::name('tagindex')->where([
372
+                    'tag'  => ['IN', $tagsArr],
373
+                    'lang'      => $this->admin_lang,
374
+                ])->column('tag');
375
+            foreach ($tagsArr as $key => $val) {
376
+                if(empty($val) || in_array($val, $tagsList)) continue;
377
+
378
+                $addData[] = [
379
+                    'tag'               => $val,
380
+                    'typeid'            => 0,
381
+                    'seo_description'   => '',
382
+                    'lang'              => $this->admin_lang,
383
+                    'add_time'          => getTime(),
384
+                    'update_time'       => getTime(),
385
+                ];
386
+            }
387
+            if (!empty($addData)) {
388
+                $r = model('Tagindex')->saveAll($addData);
389
+                if ($r !== false) {
390
+                    eyou_statistics_data(8, count($addData)); // 统计tags数
391
+                    Cache::clear('taglist');
392
+                    adminLog('批量新增Tag标签:'.get_arr_column($addData, 'tag'));
393
+                    $this->success('操作成功!');
394
+                } else {
395
+                    $this->error('操作失败');
396
+                }
397
+            } else {
398
+                $this->success('操作成功!');
399
+            }
400
+        }
401
+        return $this->fetch();
402
+    }
403
+
404
+    public function edit_index_seo()
405
+    {
406
+        if (IS_POST) {
407
+            $post = input('post.');
408
+            tpCache('tag', $post);
409
+            $this->success('操作成功');
410
+        }
411
+
412
+        $data = tpCache('tag');
413
+        $this->assign('data', $data);
414
+
415
+        return $this->fetch();
416
+    }
417
+
418
+    public function relation_archives()
419
+    {
420
+        $assign_data = array();
421
+        $condition = array();
422
+        // 获取到所有URL参数
423
+        $param = input('param.');
424
+        $typeid = input('param.typeid/d');
425
+        $channels = input('param.channel/s');
426
+
427
+        // 应用搜索条件
428
+        foreach (['keywords','typeid','channel'] as $key) {
429
+            if ($key == 'keywords' && !empty($param[$key])) {
430
+                $param[$key] = trim($param[$key]);
431
+                $condition['a.title'] = array('LIKE', "%{$param[$key]}%");
432
+            } else if ($key == 'typeid' && !empty($param[$key])) {
433
+                $typeid = $param[$key];
434
+                $hasRow = model('Arctype')->getHasChildren($typeid);
435
+                $typeids = get_arr_column($hasRow, 'id');
436
+                /*权限控制 by 小虎哥*/
437
+                $admin_info = session('admin_info');
438
+                if (0 < intval($admin_info['role_id'])) {
439
+                    $auth_role_info = $admin_info['auth_role_info'];
440
+                    if(! empty($auth_role_info)){
441
+                        if(isset($auth_role_info['only_oneself']) && 1 == $auth_role_info['only_oneself']){
442
+                            $condition['a.admin_id'] = $admin_info['admin_id'];
443
+                        }
444
+                        if(! empty($auth_role_info['permission']['arctype'])){
445
+                            if (!empty($typeid)) {
446
+                                $typeids = array_intersect($typeids, $auth_role_info['permission']['arctype']);
447
+                            }
448
+                        }
449
+                    }
450
+                }
451
+                /*--end*/
452
+                $condition['a.typeid'] = array('IN', $typeids);
453
+            } else if ($key == 'channel') {
454
+                if (empty($param[$key])) {
455
+                    $allow_release_channel = config('global.allow_release_channel');
456
+                    $key_tmp = array_search('7', $allow_release_channel);
457
+                    if (is_numeric($key_tmp) && 0 <= $key_tmp) {
458
+                        unset($allow_release_channel[$key_tmp]);
459
+                    }
460
+                    $param[$key] = implode(',', $allow_release_channel);
461
+                }
462
+                $condition['a.'.$key] = array('in', explode(',', $param[$key]));
463
+            } else if (!empty($param[$key])) {
464
+                $condition['a.'.$key] = array('eq', $param[$key]);
465
+            }
466
+        }
467
+
468
+        $condition['a.arcrank'] = array('gt', -1);
469
+        $condition['a.lang'] = array('eq', $this->admin_lang);
470
+        $condition['a.is_del'] = array('eq', 0);
471
+
472
+        /**
473
+         * 数据查询,搜索出主键ID的值
474
+         */
475
+        $count = Db::name('archives')->alias('a')->where($condition)->count('aid');// 查询满足要求的总记录数
476
+        $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
477
+        $list = Db::name('archives')
478
+            ->field("a.aid")
479
+            ->alias('a')
480
+            ->where($condition)
481
+            ->order('a.sort_order asc, a.aid desc')
482
+            ->limit($Page->firstRow.','.$Page->listRows)
483
+            ->getAllWithIndex('aid');
484
+
485
+        /**
486
+         * 完善数据集信息
487
+         * 在数据量大的情况下,经过优化的搜索逻辑,先搜索出主键ID,再通过ID将其他信息补充完整;
488
+         */
489
+        if ($list) {
490
+            $aids = array_keys($list);
491
+            $fields = "b.*, a.*, a.aid as aid";
492
+            $row = Db::name('archives')
493
+                ->field($fields)
494
+                ->alias('a')
495
+                ->join('__ARCTYPE__ b', 'a.typeid = b.id', 'LEFT')
496
+                ->where('a.aid', 'in', $aids)
497
+                ->getAllWithIndex('aid');
498
+            foreach ($list as $key => $val) {
499
+                $list[$key] = $row[$val['aid']];
500
+            }
501
+        }
502
+        $show = $Page->show();
503
+        $assign_data['page'] = $show;
504
+        $assign_data['list'] = $list;
505
+        $assign_data['pager'] = $Page;
506
+
507
+        /*允许发布文档列表的栏目*/
508
+        $allow_release_channel = !empty($channels) ? explode(',', $channels) : config('global.allow_release_channel');
509
+        $key_tmp = array_search('7', $allow_release_channel);
510
+        if (is_numeric($key_tmp) && 0 <= $key_tmp) {
511
+            unset($allow_release_channel[$key_tmp]);
512
+        }
513
+        $assign_data['arctype_html'] = allow_release_arctype($typeid, $allow_release_channel);
514
+        /*--end*/
515
+        
516
+        // 模型列表
517
+        $channeltype_list = getChanneltypeList();
518
+        $this->assign('channeltype_list', $channeltype_list);
519
+
520
+        // 当前页已关联的文档
521
+        $tid = input('param.tid/d');
522
+        $tagaids_str = $this->readTagaidsFile();
523
+        if (empty($tagaids_str)) {
524
+            $tagaids = Db::name('taglist')->where(['tid'=>$tid])->column('aid');
525
+            $tagaids_str = implode(',', $tagaids);
526
+            $this->writeTagaidsFile($tagaids_str);
527
+        }
528
+        $assign_data['tid'] = $tid;
529
+
530
+        $this->assign($assign_data);
531
+        
532
+        return $this->fetch();
533
+    }
534
+
535
+    public function relation_archives_save()
536
+    {
537
+        if (IS_POST) {
538
+            $tid = input('param.tid/d');
539
+            $tagaids = input('post.tagaids/s');
540
+            if (empty($tagaids)) {
541
+                $tagaids = $this->readTagaidsFile();
542
+            }
543
+            $tagaids = trim($tagaids, ',');
544
+            $aids_new = [];
545
+            if (!empty($tagaids)) {
546
+                $aids_new = explode(',', $tagaids);
547
+            }
548
+            if (!empty($tid)) {
549
+                $tag = Db::name('tagindex')->where(['id'=>$tid])->value('tag');
550
+                $aids_old = Db::name('taglist')->where(['tid'=>$tid])->column('aid');
551
+                empty($aids_old) && $aids_old = [];
552
+
553
+                // 取消关联文档
554
+                $delaids = array_diff($aids_old, $aids_new);
555
+                if (!empty($delaids)) {
556
+                    Db::name('taglist')->where(['aid'=>['IN', $delaids]])->delete();
557
+                }
558
+                // 追加关联的文档ID
559
+                $addaids = array_diff($aids_new, $aids_old);
560
+                if (!empty($addaids)) {
561
+                    $archivesList = Db::name('archives')->field('aid,typeid,arcrank')->where(['aid'=>['in', $addaids]])->select();
562
+                    $saveData = [];
563
+                    foreach ($archivesList as $key => $val) {
564
+                        $saveData[] = [
565
+                            'tid'   => $tid,
566
+                            'aid'   => $val['aid'],
567
+                            'typeid'=> $val['typeid'],
568
+                            'tag'   => $tag,
569
+                            'arcrank'=> $val['arcrank'],
570
+                            'lang'  => $this->admin_lang,
571
+                            'add_time'=> getTime(),
572
+                            'update_time'=> getTime(),
573
+                        ];
574
+                    }
575
+                    !empty($saveData) && model('Taglist')->saveAll($saveData);
576
+                }
577
+                // 更新文档总数
578
+                Db::name('tagindex')->where(['id'=>$tid])->update([
579
+                    'total' => count($aids_new),
580
+                    'update_time'   => getTime(),
581
+                ]);
582
+                Cache::clear('taglist');
583
+                adminLog('Tag关联文档:'.$tagaids);
584
+                $this->success('操作成功', url('Tags/relation_archives', ['tid'=>$tid]));
585
+            }
586
+            $this->error('操作失败');
587
+        }
588
+    }
589
+
590
+    /**
591
+     * 用于Tag关联文档的逻辑
592
+     * @return [type] [description]
593
+     */
594
+    public function ajax_recordfile()
595
+    {
596
+        \think\Session::pause(); // 暂停session,防止session阻塞机制
597
+        if (IS_AJAX) {
598
+            $opt = input('param.opt/s');
599
+            $value = input('param.value/s');
600
+            $filename = ROOT_PATH . 'data/conf/tagaids_1619141574.txt';
601
+            if ('set' == $opt) {
602
+                $redata = $this->writeTagaidsFile($value);
603
+                if (true !== $redata) {
604
+                    $this->error($redata);
605
+                }
606
+                $this->success('写入成功!');
607
+            }
608
+            else if ('get' == $opt) {
609
+                $tagaids = $this->readTagaidsFile();
610
+                $this->success('读取成功!', null, $tagaids);
611
+            }
612
+        }
613
+    }
614
+
615
+    /**
616
+     * 读取关联tagaids文件 - 应用于tag关联文档
617
+     * @return [type] [description]
618
+     */
619
+    private function readTagaidsFile()
620
+    {
621
+        $tagaids = '';
622
+        $filename = ROOT_PATH . 'data/conf/tagaids_1619141574.txt';
623
+        if (file_exists($filename)) {
624
+            $len     = filesize($filename);
625
+            if (!empty($len) && $len > 0) {
626
+                $fp      = fopen($filename, 'r');
627
+                $tagaids = fread($fp, $len);
628
+                fclose($fp);
629
+                $tagaids = $tagaids ? $tagaids : '';
630
+            }
631
+        }
632
+        return $tagaids;
633
+    }
634
+
635
+    /**
636
+     * 写入关联tagaids文件 - 应用于tag关联文档
637
+     * @return [type] [description]
638
+     */
639
+    private function writeTagaidsFile($value = '')
640
+    {
641
+        $filename = ROOT_PATH . 'data/conf/tagaids_1619141574.txt';
642
+        if (!file_exists($filename)) tp_mkdir(dirname($filename));
643
+        $fp = fopen($filename, "w+");
644
+        if (empty($fp)) {
645
+            return "请设置" . $filename . "的权限为744";
646
+        } else {
647
+            if (fwrite($fp, $value)) {
648
+                fclose($fp);
649
+            }
650
+        }
651
+        return true;
652
+    }
653
+}

+ 556
- 0
application/admin/controller/Tools.php View File

@@ -0,0 +1,556 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use think\Db;
16
+use think\Backup;
17
+
18
+class Tools extends Base {
19
+
20
+    public function _initialize() {
21
+        parent::_initialize();
22
+        $this->language_access(); // 多语言功能操作权限
23
+    }
24
+    
25
+    /**
26
+     * 数据表列表
27
+     */
28
+    public function index()
29
+    {
30
+        $dbtables = Db::query('SHOW TABLE STATUS');
31
+        $total = 0;
32
+        $list = array();
33
+        foreach ($dbtables as $k => $v) {
34
+            if (preg_match('/^'.PREFIX.'/i', $v['Name'])) {
35
+                $v['size'] = format_bytes($v['Data_length'] + $v['Index_length']);
36
+                $list[$k] = $v;
37
+                $total += $v['Data_length'] + $v['Index_length'];
38
+            }
39
+        }
40
+        $path = tpCache('global.web_sqldatapath');
41
+        $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
42
+        if (file_exists(realpath(trim($path, '/')) . DS . 'backup.lock')) {
43
+            @unlink(realpath(trim($path, '/')) . DS . 'backup.lock');
44
+        }
45
+        // if (session('?backup_config.path')) {
46
+            //备份完成,清空缓存
47
+            session('backup_tables', null);
48
+            session('backup_file', null);
49
+            session('backup_config', null);
50
+        // }
51
+        $this->assign('list', $list);
52
+        $this->assign('total', format_bytes($total));
53
+        $this->assign('tableNum', count($list));
54
+        return $this->fetch();
55
+    }
56
+
57
+    /**
58
+     * 数据备份
59
+     */
60
+    public function export($tables = null, $id = null, $start = null,$optstep = 0)
61
+    {
62
+        //防止备份数据过程超时
63
+        function_exists('set_time_limit') && set_time_limit(0);
64
+        @ini_set('memory_limit','-1');
65
+
66
+        /*升级完自动备份所有数据表*/
67
+        if ('all' == $tables) {
68
+            $dbtables = Db::query('SHOW TABLE STATUS');
69
+            $list = array();
70
+            foreach ($dbtables as $k => $v) {
71
+                if (preg_match('/^'.PREFIX.'/i', $v['Name'])) {
72
+                    $list[] = $v['Name'];
73
+                }
74
+            }
75
+            $tables = $list;
76
+            unlink(session('backup_config.path') . 'backup.lock');
77
+        }
78
+        /*--end*/
79
+
80
+        if(IS_POST && !empty($tables) && is_array($tables) && empty($optstep)){ //初始化
81
+
82
+            /*多语言*/
83
+            $tpCacheData = ['php_atqueryrequest_time'=>0, 'php_atqueryrequest_time2'=>0];
84
+            if (is_language()) {
85
+                $langRow = \think\Db::name('language')->order('id asc')->select();
86
+                foreach ($langRow as $key => $val) {
87
+                    tpCache('php', $tpCacheData, $val['mark']); // n
88
+                }
89
+            } else { // 单语言
90
+                tpCache('php', $tpCacheData); // n
91
+            }
92
+            /*--end*/
93
+
94
+            $path = tpCache('global.web_sqldatapath');
95
+            $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
96
+            $path = trim($path, '/');
97
+            if(!empty($path) && !is_dir($path)){
98
+                mkdir($path, 0755, true);
99
+            }
100
+
101
+            //读取备份配置
102
+            $config = array(
103
+                'path'     => realpath($path) . DS,
104
+                'part'     => config('DATA_BACKUP_PART_SIZE'),
105
+                'compress' => config('DATA_BACKUP_COMPRESS'),
106
+                'level'    => config('DATA_BACKUP_COMPRESS_LEVEL'),
107
+            );
108
+
109
+            //检查备份目录是否可写
110
+            if(!is_writeable($config['path'])){
111
+                return json(array('msg'=>'备份目录不存在或不可写,请检查后重试!', 'code'=>0, 'url'=>''));
112
+            }
113
+            //检查是否有正在执行的任务
114
+            $lock = "{$config['path']}backup.lock";
115
+            if(is_file($lock)){
116
+                return json(array('msg'=>'检测到有一个备份任务正在执行,请稍后再试!', 'code'=>0, 'url'=>''));
117
+            } else {
118
+                //创建锁文件
119
+                file_put_contents($lock, $_SERVER['REQUEST_TIME']);
120
+                session('backup_config', $config);
121
+            }
122
+
123
+            //生成备份文件信息
124
+            $file = array(
125
+                'name' => date('Ymd-His'),
126
+                'part' => 1,
127
+                'version' => getCmsVersion(),
128
+            );
129
+            session('backup_file', $file);
130
+            //缓存要备份的表
131
+            session('backup_tables', $tables);
132
+            //创建备份文件
133
+            $Database = new Backup($file, $config);
134
+            if(false !== $Database->create()){
135
+                $speed = (floor((1/count($tables))*10000)/10000*100);
136
+                $speed = sprintf("%.2f", $speed);
137
+                $tab = array('id' => 0, 'start' => 0, 'speed'=>$speed, 'table'=>$tables[0], 'optstep'=>1);
138
+                return json(array('tables' => $tables, 'tab' => $tab, 'msg'=>'初始化成功!', 'code'=>1, 'url'=>''));
139
+            } else {
140
+                return json(array('msg'=>'初始化失败,备份文件创建失败!', 'code'=>0, 'url'=>''));
141
+            }
142
+        } elseif (IS_POST && is_numeric($id) && is_numeric($start) && 1 == intval($optstep)) { //备份数据
143
+            $tables = session('backup_tables');
144
+            //备份指定表
145
+            $Database = new Backup(session('backup_file'), session('backup_config'));
146
+            $start  = $Database->backup($tables[$id], $start);
147
+            if(false === $start){ //出错
148
+                return json(array('msg'=>'备份出错!', 'code'=>0, 'url'=>''));
149
+            } elseif (0 === $start) { //下一表
150
+                if(isset($tables[++$id])){
151
+                    $speed = (floor((($id+1)/count($tables))*10000)/10000*100);
152
+                    $speed = sprintf("%.2f", $speed);
153
+                    $tab = array('id' => $id, 'start' => 0, 'speed' => $speed, 'table'=>$tables[$id], 'optstep'=>1);
154
+                    return json(array('tab' => $tab, 'msg'=>'备份完成!', 'code'=>1, 'url'=>''));
155
+                }
156
+                else { //备份完成,清空缓存
157
+                    
158
+                    /*自动覆盖安装目录下的eyoucms.sql*/
159
+                    $install_path = ROOT_PATH.'install';
160
+                    if (!is_dir($install_path) || !file_exists($install_path)) {
161
+                        $dirlist = glob('install_*');
162
+                        $install_dirname = current($dirlist);
163
+                        if (!empty($install_dirname)) {
164
+                            $install_path = ROOT_PATH.$install_dirname;
165
+                        }
166
+                    }
167
+                    if (is_dir($install_path) && file_exists($install_path)) {
168
+                        $srcfile = session('backup_config.path').session('backup_file.name').'-'.session('backup_file.part').'-'.session('backup_file.version').'.sql';
169
+                        $dstfile = $install_path.'/eyoucms.sql';
170
+                        if(@copy($srcfile, $dstfile)){
171
+                            /*替换所有表的前缀为官方默认ey_,并重写安装数据包里*/
172
+                            $eyouDbStr = @file_get_contents($dstfile);
173
+                            if (!empty($eyouDbStr)) {
174
+                                $dbtables = Db::query('SHOW TABLE STATUS');
175
+                                $tableName = $eyTableName = [];
176
+                                foreach ($dbtables as $k => $v) {
177
+                                    if (preg_match('/^'.PREFIX.'/i', $v['Name'])) {
178
+                                        $tableName[] = "`{$v['Name']}`";
179
+                                        $eyTableName[] = preg_replace('/^`'.PREFIX.'/i', '`ey_', "`{$v['Name']}`");
180
+                                    }
181
+                                }
182
+                                foreach ($tableName as $key => $val) {
183
+                                    if ($val != $eyTableName[$key]) {
184
+                                        $eyouDbStr = str_replace($tableName, $eyTableName, $eyouDbStr);
185
+                                    }
186
+                                }
187
+                                @file_put_contents($dstfile, $eyouDbStr);
188
+                                unset($eyouDbStr);
189
+                            }
190
+                            /*--end*/
191
+                        } else {
192
+                            @unlink($dstfile); // 复制失败就删掉,避免安装错误的数据包
193
+                        }
194
+                    }
195
+                    /*--end*/
196
+                    @unlink(session('backup_config.path') . 'backup.lock');
197
+                    session('backup_tables', null);
198
+                    session('backup_file', null);
199
+                    session('backup_config', null);
200
+                    adminLog('备份数据库');
201
+                    return json(array('msg'=>'备份完成!', 'code'=>1, 'url'=>''));
202
+                }
203
+            } else {
204
+                $rate = floor(100 * ($start[0] / $start[1]));
205
+                $speed = floor((($id+1)/count($tables))*10000)/10000*100 + ($rate/100);
206
+                $speed = sprintf("%.2f", $speed);
207
+                $tab  = array('id' => $id, 'start' => $start[0], 'speed' => $speed, 'table'=>$tables[$id], 'optstep'=>1);
208
+                return json(array('tab' => $tab, 'msg'=>"正在备份...({$rate}%)", 'code'=>1, 'url'=>''));
209
+            }
210
+
211
+        } else {//出错
212
+            return json(array('msg'=>'参数有误', 'tab'=>['speed'=>-1], 'code'=>0, 'url'=>''));
213
+        }
214
+    }
215
+        
216
+    /**
217
+     * 优化
218
+     */
219
+    public function optimize()
220
+    {
221
+        $batchFlag = input('get.batchFlag', 0, 'intval');
222
+        //批量删除
223
+        if ($batchFlag) {
224
+            $table = input('key', array());
225
+        }else {
226
+            $table[] = input('tablename' , '');
227
+        }
228
+    
229
+        if (empty($table)) {
230
+            $this->error('请选择数据表');
231
+        }
232
+
233
+        $strTable = implode(',', $table);
234
+        if (!DB::query("OPTIMIZE TABLE {$strTable} ")) {
235
+            $strTable = '';
236
+        }
237
+        adminLog('优化数据库:'.$strTable);
238
+        $this->success("操作成功" . $strTable, url('Tools/index'));
239
+    
240
+    }
241
+    
242
+    /**
243
+     * 修复
244
+     */
245
+    public function repair()
246
+    {
247
+        $batchFlag = input('get.batchFlag', 0, 'intval');
248
+        //批量删除
249
+        if ($batchFlag) {
250
+            $table = input('key', array());
251
+        }else {
252
+            $table[] = input('tablename' , '');
253
+        }
254
+    
255
+        if (empty($table)) {
256
+            $this->error('请选择数据表');
257
+        }
258
+    
259
+        $strTable = implode(',', $table);
260
+        if (!DB::query("REPAIR TABLE {$strTable} ")) {
261
+            $strTable = '';
262
+        }
263
+        adminLog('修复数据库:'.$strTable);
264
+        $this->success("操作成功" . $strTable, url('Tools/index'));
265
+  
266
+    }
267
+
268
+    /**
269
+     * 数据还原
270
+     */
271
+    public function restore()
272
+    {
273
+        $path = tpCache('global.web_sqldatapath');
274
+        $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
275
+        $path = trim($path, '/');
276
+        if(!empty($path) && !is_dir($path)){
277
+            mkdir($path, 0755, true);
278
+        }
279
+        $path = realpath($path);
280
+        $flag = \FilesystemIterator::KEY_AS_FILENAME;
281
+        $glob = new \FilesystemIterator($path,  $flag);
282
+        $list = array();
283
+        $filenum = $total = 0;
284
+        foreach ($glob as $name => $file) {
285
+            if(preg_match('/^\d{8,8}-\d{6,6}-\d+-v\d+\.\d+\.\d+(.*)\.sql(?:\.gz)?$/', $name)){
286
+                $name = sscanf($name, '%4s%2s%2s-%2s%2s%2s-%d-%s');
287
+                $date = "{$name[0]}-{$name[1]}-{$name[2]}";
288
+                $time = "{$name[3]}:{$name[4]}:{$name[5]}";
289
+                $part = $name[6];
290
+                $version = preg_replace('#\.sql(.*)#i', '', $name[7]);
291
+                $info = pathinfo($file);
292
+                if(isset($list["{$date} {$time}"])){
293
+                    $info = $list["{$date} {$time}"];
294
+                    $info['part'] = max($info['part'], $part);
295
+                    $info['size'] = $info['size'] + $file->getSize();
296
+                } else {
297
+                    $info['part'] = $part;
298
+                    $info['size'] = $file->getSize();
299
+                }
300
+                $info['compress'] = ($info['extension'] === 'sql') ? '-' : $info['extension'];
301
+                $info['time']  = strtotime("{$date} {$time}");
302
+                $info['version']  = $version;
303
+                $filenum++;
304
+                $total += $info['size'];
305
+                $list["{$date} {$time}"] = $info;
306
+            }
307
+        }
308
+        array_multisort($list, SORT_DESC);
309
+        $this->assign('list', $list);
310
+        $this->assign('filenum',$filenum);
311
+        $this->assign('total',$total);
312
+        return $this->fetch();
313
+    }
314
+
315
+    /**
316
+     * 上传sql文件
317
+     */
318
+    public function restoreUpload()
319
+    {
320
+        $this->error('该功能仅限技术人员使用!');
321
+        
322
+        $file = request()->file('sqlfile');
323
+        if(empty($file)){
324
+            $this->error('请上传sql文件');
325
+        }
326
+        // 移动到框架应用根目录/data/sqldata/ 目录下
327
+        $path = tpCache('global.web_sqldatapath');
328
+        $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
329
+        $path = trim($path, '/');
330
+        $image_upload_limit_size = intval(tpCache('basic.file_size') * 1024 * 1024);
331
+        $info = $file->validate(['size'=>$image_upload_limit_size,'ext'=>'sql,gz'])->move($path, $_FILES['sqlfile']['name']);
332
+        if ($info) {
333
+            //上传成功 获取上传文件信息
334
+            $file_path_full = $info->getPathName();
335
+            if (file_exists($file_path_full)) {
336
+                $sqls = Backup::parseSql($file_path_full);
337
+                if(Backup::install($sqls)){
338
+                    /*清除缓存*/
339
+                    delFile(RUNTIME_PATH);
340
+                    /*--end*/
341
+                    $this->success("执行sql成功", url('Tools/restore'));
342
+                }else{
343
+                    $this->error('执行sql失败');
344
+                }
345
+            } else {
346
+                $this->error('sql文件上传失败');
347
+            }
348
+        } else {
349
+            //上传错误提示错误信息
350
+            $this->error($file->getError());
351
+        }
352
+    }
353
+
354
+    /**
355
+     * 执行还原数据库操作
356
+     * @param int $time
357
+     * @param null $part
358
+     * @param null $start
359
+     */
360
+    public function import($time = 0, $part = null, $start = null)
361
+    {
362
+        function_exists('set_time_limit') && set_time_limit(0);
363
+
364
+        if(is_numeric($time) && is_null($part) && is_null($start)){ //初始化
365
+            //获取备份文件信息
366
+            $name  = date('Ymd-His', $time) . '-*.sql*';
367
+            $path = tpCache('global.web_sqldatapath');
368
+            $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
369
+            $path = trim($path, '/');
370
+            $path  = realpath($path) . DS . $name;
371
+            $files = glob($path);
372
+            $list  = array();
373
+            foreach($files as $name){
374
+                $basename = basename($name);
375
+                $match    = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d');
376
+                $gz       = preg_match('/^\d{8,8}-\d{6,6}-\d+\.sql.gz$/', $basename);
377
+                $list[$match[6]] = array($match[6], $name, $gz);
378
+            }
379
+            ksort($list);
380
+
381
+            //检测文件正确性
382
+            $last = end($list);
383
+            if(count($list) === $last[0]){
384
+                session('backup_list', $list); //缓存备份列表
385
+                $part = 1;
386
+                $start = 0;
387
+                $data = array('part' => $part, 'start' => $start);
388
+                // $this->success('初始化完成!', null, array('part' => $part, 'start' => $start));
389
+                respose(array('code'=>1, 'msg'=>"初始化完成!准备还原#{$part}...", 'rate'=>'', 'data'=>$data));
390
+            } else {
391
+                // $this->error('备份文件可能已经损坏,请检查!');
392
+                respose(array('code'=>0, 'msg'=>"备份文件可能已经损坏,请检查!"));
393
+            }
394
+        } elseif(is_numeric($part) && is_numeric($start)) {
395
+            $list  = session('backup_list');
396
+            $path = tpCache('global.web_sqldatapath');
397
+            $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
398
+            $path = trim($path, '/');
399
+            $db = new Backup($list[$part], array(
400
+                    'path'     => realpath($path) . DS,
401
+                    'compress' => $list[$part][2]));
402
+            $start = $db->import($start);
403
+            if(false === $start){
404
+                // $this->error('还原数据出错!');
405
+                respose(array('code'=>0, 'msg'=>"还原数据出错!", 'rate'=>'0%'));
406
+            } elseif(0 === $start) { //下一卷
407
+                if(isset($list[++$part])){
408
+                    $data = array('part' => $part, 'start' => 0);
409
+                    // $this->success("正在还g原...#{$part}", null, $data);
410
+                    $rate = (floor((($start+1)/count($list))*10000)/10000*100).'%';
411
+                    respose(array('code'=>1, 'msg'=>"正在还原#{$part}...", 'rate'=>$rate, 'data'=>$data));
412
+                } else {
413
+                    adminLog('还原数据库');
414
+                    session('backup_list', null);
415
+                    delFile(RUNTIME_PATH);
416
+                    respose(array('code'=>1, 'msg'=>"还原完成...", 'rate'=>'100%'));
417
+                    // $this->success('还原完成!');
418
+                }
419
+            } else {
420
+                $data = array('part' => $part, 'start' => $start[0]);
421
+                if($start[1]){
422
+                    $rate = floor(100 * ($start[0] / $start[1])).'%';
423
+                    respose(array('code'=>1, 'msg'=>"正在还原#{$part}...", 'rate'=>$rate, 'data'=>$data));
424
+                    // $this->success("正在还d原...#{$part} ({$rate}%)", null, $data);
425
+                } else {
426
+                    $data['gz'] = 1;
427
+                    respose(array('code'=>1, 'msg'=>"正在还原#{$part}...", 'data'=>$data, 'start'=>$start));
428
+                    // $this->success("正在还s原...#{$part}", null, $data);
429
+                }
430
+            }
431
+        } else {
432
+            // $this->error('参数错误!');
433
+            respose(array('code'=>0, 'msg'=>"参数有误", 'rate'=>'0%'));
434
+        }
435
+    }
436
+
437
+    /**
438
+     * (新)执行还原数据库操作
439
+     * @param int $time
440
+     */
441
+    public function new_import($time = 0)
442
+    {
443
+        function_exists('set_time_limit') && set_time_limit(0);
444
+        @ini_set('memory_limit','-1');
445
+
446
+        if(is_numeric($time) && intval($time) > 0){
447
+            //获取备份文件信息
448
+            $name  = date('Ymd-His', $time) . '-*.sql*';
449
+            $path = tpCache('global.web_sqldatapath');
450
+            $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
451
+            $path = trim($path, '/');
452
+            $path  = realpath($path) . DS . $name;
453
+            $files = glob($path);
454
+            $list  = array();
455
+            foreach($files as $name){
456
+                $basename = basename($name);
457
+                $match    = sscanf($basename, '%4s%2s%2s-%2s%2s%2s-%d-%s');
458
+                $gz       = preg_match('/^\d{8,8}-\d{6,6}-\d+-v\d+\.\d+\.\d+(.*)\.sql.gz$/', $basename);
459
+                $list[$match[6]] = array($match[6], $name, $gz);
460
+            }
461
+            ksort($list);
462
+
463
+            //检测文件正确性
464
+            $last = end($list);
465
+            $file_path_full = !empty($last[1]) ? $last[1] : '';
466
+            if (file_exists($file_path_full)) {
467
+                /*校验sql文件是否属于当前CMS版本*/
468
+                preg_match('/(\d{8,8})-(\d{6,6})-(\d+)-(v\d+\.\d+\.\d+(.*))\.sql/i', $file_path_full, $matches);
469
+                $version = getCmsVersion();
470
+                if ($matches[4] != $version) {
471
+                    $this->error('sql不兼容当前版本:'.$version, url('Tools/restore'));
472
+                }
473
+                /*--end*/
474
+                $new_path = tpCache('web.web_sqldatapath');
475
+                $sqls = Backup::parseSql($file_path_full);
476
+                if (Backup::install($sqls)) {
477
+                    //修改数据库备份目录为原来的目录
478
+                    $tpCacheData = ['web_sqldatapath'=>$new_path, 'php_atqueryrequest_time'=>0, 'php_atqueryrequest_time2'=>0];
479
+                    if (is_language()) {
480
+                        $langRow = Db::name('language')->order('id asc')->select();
481
+                        foreach ($langRow as $key => $val) {
482
+                            tpCache('web', $tpCacheData, $val['mark']);
483
+                        }
484
+                    } else { // 单语言
485
+                        tpCache('web', $tpCacheData);
486
+                    }
487
+                    delFile(RUNTIME_PATH); // 清除缓存
488
+                    adminLog('还原数据库');
489
+                    verify_authortoken();
490
+                    $this->success('操作成功', request()->baseFile(), '', 1, [], '_parent');
491
+                }else{
492
+                    $this->error('操作失败!', url('Tools/restore'));
493
+                }
494
+            }
495
+        }
496
+        else 
497
+        {
498
+            $this->error("参数有误", url('Tools/restore'));
499
+        }
500
+        exit;
501
+    }
502
+
503
+    /**
504
+     * 下载
505
+     * @param int $time
506
+     */
507
+    public function downFile($time = 0)
508
+    {
509
+        $name  = date('Ymd-His', $time) . '-*.sql*';
510
+        $path = tpCache('global.web_sqldatapath');
511
+        $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
512
+        $path = trim($path, '/');
513
+        $path  = realpath($path) . DS . $name;
514
+        $files = glob($path);
515
+        if(is_array($files)){
516
+            foreach ($files as $filePath){
517
+                if (!file_exists($filePath)) {
518
+                    $this->error("该文件不存在,可能是被删除");
519
+                }else{
520
+                    $filename = basename($filePath);
521
+                    header("Content-type: application/octet-stream");
522
+                    header('Content-Disposition: attachment; filename="' . $filename . '"');
523
+                    header("Content-Length: " . filesize($filePath));
524
+                    readfile($filePath);
525
+                }
526
+            }
527
+        }
528
+    }
529
+
530
+    /**
531
+     * 删除备份文件
532
+     * @param  Integer $time 备份时间
533
+     */
534
+    public function del()
535
+    {
536
+        $time_arr = input('del_id/a');
537
+        $time_arr = eyIntval($time_arr);
538
+        if(is_array($time_arr) && !empty($time_arr)){
539
+            foreach ($time_arr as $key => $val) {
540
+                $name  = date('Ymd-His', $val) . '-*.sql*';
541
+                $path = tpCache('global.web_sqldatapath');
542
+                $path = !empty($path) ? $path : config('DATA_BACKUP_PATH');
543
+                $path = trim($path, '/');
544
+                $path  = realpath($path) . DS . $name;
545
+                array_map("unlink", glob($path));
546
+                if(count(glob($path))){
547
+                    $this->error('备份文件删除失败,请检查目录权限!');
548
+                }
549
+            }
550
+            adminLog('删除数据库备份文件');
551
+            $this->success('删除成功!');
552
+        } else {
553
+            $this->error('参数有误');
554
+        }
555
+    }
556
+}

+ 1011
- 0
application/admin/controller/Ueditor.php
File diff suppressed because it is too large
View File


+ 162
- 0
application/admin/controller/Uiset.php View File

@@ -0,0 +1,162 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+
19
+class Uiset extends Base
20
+{
21
+    public $theme_style;
22
+    public $templateArr = array();
23
+
24
+    /*
25
+     * 初始化操作
26
+     */
27
+    public function _initialize() {
28
+        parent::_initialize();
29
+        $this->theme_style = 'pc';
30
+
31
+        /*模板列表*/
32
+        if (file_exists(ROOT_PATH.'template/'.TPL_THEME.'pc/uiset.txt')) {
33
+            array_push($this->templateArr, 'pc');
34
+        }
35
+        if (file_exists(ROOT_PATH.'template/'.TPL_THEME.'mobile/uiset.txt')) {
36
+            array_push($this->templateArr, 'mobile');
37
+        }
38
+        /*--end*/
39
+
40
+        /*权限控制 by 小虎哥*/
41
+        $admin_info = session('admin_info');
42
+        if (0 < intval($admin_info['role_id'])) {
43
+            $auth_role_info = $admin_info['auth_role_info'];
44
+            $permission = $auth_role_info['permission'];
45
+            $auth_rule = get_auth_rule();
46
+            $all_auths = []; // 系统全部权限对应的菜单ID
47
+            $admin_auths = []; // 用户当前拥有权限对应的菜单ID
48
+            $diff_auths = []; // 用户没有被授权的权限对应的菜单ID
49
+            foreach($auth_rule as $key => $val){
50
+                $all_auths = array_merge($all_auths, explode(',', $val['menu_id']), explode(',', $val['menu_id2']));
51
+                if (in_array($val['id'], $permission['rules'])) {
52
+                    $admin_auths = array_merge($admin_auths, explode(',', $val['menu_id']), explode(',', $val['menu_id2']));
53
+                }
54
+            }
55
+            $all_auths = array_unique($all_auths);
56
+            $admin_auths = array_unique($admin_auths);
57
+            $diff_auths = array_diff($all_auths, $admin_auths);
58
+
59
+            if(in_array(2002, $diff_auths)){
60
+                $this->error('您没有操作权限,请联系超级管理员分配权限');
61
+            }
62
+        }
63
+        /*--end*/
64
+    }
65
+
66
+    /**
67
+     * PC调试外观
68
+     */
69
+    public function pc()
70
+    {
71
+        // 支持子目录
72
+        $index_url = ROOT_DIR.'/index.php?m=home&c=Index&a=index&uiset=on&v=pc&lang='.$this->admin_lang;
73
+        $this->redirect($index_url);
74
+    }
75
+
76
+    /**
77
+     * 手机调试外观
78
+     */
79
+    public function mobile()
80
+    {
81
+        // 支持子目录
82
+        $index_url = ROOT_DIR.'/index.php?m=home&c=Index&a=index&uiset=on&v=mobile&lang='.$this->admin_lang;
83
+        $this->redirect($index_url);
84
+    }
85
+
86
+    /**
87
+     * 调试外观
88
+     */
89
+    public function index()
90
+    {
91
+        return $this->fetch();
92
+    }
93
+
94
+    /**
95
+     * 数据列表
96
+     */
97
+    public function ui_index()
98
+    {
99
+        $condition = array();
100
+        // 获取到所有GET参数
101
+        $param = input('param.');
102
+        /*模板主题*/
103
+        $param['theme_style'] = $this->theme_style = input('param.theme_style/s', 'pc');
104
+        /*--end*/
105
+
106
+        // 应用搜索条件
107
+        foreach (['keywords','theme_style'] as $key) {
108
+            if (isset($param[$key]) && $param[$key] !== '') {
109
+                if ($key == 'keywords') {
110
+                    $condition['a.page|a.type|a.name'] = array('eq', "%{$param[$key]}%");
111
+                } else if ($key == 'theme_style') {
112
+                    $condition['a.'.$key] = array('eq', TPL_THEME.$param[$key]);
113
+                } else {
114
+                    $condition['a.'.$key] = array('eq', $param[$key]);
115
+                }
116
+            }
117
+        }
118
+
119
+        /*多语言*/
120
+        $condition['a.lang'] = $this->admin_lang;
121
+        /*--end*/
122
+
123
+        $list = array();
124
+
125
+        $uiconfigM =  Db::name('ui_config');
126
+        $count = $uiconfigM->alias('a')->where($condition)->count('id');// 查询满足要求的总记录数
127
+        $Page = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
128
+        $list = $uiconfigM->alias('a')->where($condition)->order('id desc')->limit($Page->firstRow.','.$Page->listRows)->select();
129
+
130
+        $show = $Page->show();// 分页显示输出
131
+        $this->assign('page',$show);// 赋值分页输出
132
+        $this->assign('list',$list);// 赋值数据集
133
+        $this->assign('pager',$pager);// 赋值分页对象
134
+        $this->assign('theme_style',$this->theme_style);// 模板主题
135
+        $this->assign('templateArr',$this->templateArr);// 模板列表
136
+
137
+        return $this->fetch();
138
+    }
139
+    
140
+    /**
141
+     * 删除
142
+     */
143
+    public function del()
144
+    {
145
+        $id_arr = input('del_id/a');
146
+        $id_arr = eyIntval($id_arr);
147
+        if(!empty($id_arr)){
148
+            $result = Db::name('ui_config')->where("id",'IN',$id_arr)->getAllWithIndex('name');
149
+            $r = Db::name('ui_config')->where("id",'IN',$id_arr)->delete();
150
+            if($r){
151
+                \think\Cache::clear('ui_config');
152
+                delFile(RUNTIME_PATH.'ui/'.$result['theme_style']);
153
+                adminLog('删除可视化数据 e-id:'.implode(array_keys($result)));
154
+                $this->success('删除成功');
155
+            }else{
156
+                $this->error('删除失败');
157
+            }
158
+        }else{
159
+            $this->error('参数有误');
160
+        }
161
+    }
162
+}

+ 329
- 0
application/admin/controller/Upgrade.php View File

@@ -0,0 +1,329 @@
1
+<?php
2
+/**
3
+ * eyoucms
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+use think\Controller;
16
+use think\Db;
17
+use think\response\Json;
18
+use app\admin\model;
19
+class Upgrade extends Controller {
20
+
21
+    /**
22
+     * 析构函数
23
+     */
24
+    function __construct() {
25
+        parent::__construct();
26
+        function_exists('set_time_limit') && set_time_limit(0);
27
+        @ini_set('memory_limit','-1');
28
+        // @ini_set('memory_limit', '1024M'); // 设置内存大小
29
+        // @ini_set("max_execution_time", "0"); // 请求超时时间 0 为不限时
30
+        // @ini_set('default_socket_timeout', 3600); // 设置 file_get_contents 请求超时时间 官方的说明,似乎没有不限时间的选项,也就是不能填0,你如果填0,那么socket就会立即返回失败,
31
+        $this->assign('version', getCmsVersion());
32
+    }
33
+
34
+    public function welcome()
35
+    {
36
+        $sys_info['os']             = PHP_OS;
37
+        $sys_info['zlib']           = function_exists('gzclose') ? 'YES' : 'NO';//zlib
38
+        $sys_info['safe_mode']      = (boolean) ini_get('safe_mode') ? 'YES' : 'NO';//safe_mode = Off       
39
+        $sys_info['timezone']       = function_exists("date_default_timezone_get") ? date_default_timezone_get() : "no_timezone";
40
+        $sys_info['curl']           = function_exists('curl_init') ? 'YES' : 'NO';  
41
+        $sys_info['web_server']     = $_SERVER['SERVER_SOFTWARE'];
42
+        $sys_info['phpv']           = phpversion();
43
+        $sys_info['ip']             = GetHostByName($_SERVER['SERVER_NAME']);
44
+        $sys_info['fileupload']     = @ini_get('file_uploads') ? ini_get('upload_max_filesize') :'unknown';
45
+        $sys_info['max_ex_time']    = @ini_get("max_execution_time").'s'; //脚本最大执行时间
46
+        $sys_info['set_time_limit'] = function_exists("set_time_limit") ? true : false;
47
+        $sys_info['domain']         = request()->host();
48
+        $sys_info['memory_limit']   = ini_get('memory_limit');                                  
49
+        $sys_info['version']        = file_get_contents(DATA_PATH.'conf/version.txt');
50
+        $mysqlinfo = Db::query("SELECT VERSION() as version");
51
+        $sys_info['mysql_version']  = $mysqlinfo[0]['version'];
52
+        if(function_exists("gd_info")){
53
+            $gd = gd_info();
54
+            $sys_info['gdinfo']     = $gd['GD Version'];
55
+        }else {
56
+            $sys_info['gdinfo']     = "未知";
57
+        }
58
+
59
+        $globalTpCache = tpCache('global');
60
+
61
+        $upgradeLogic = new \app\admin\logic\UpgradeLogic();
62
+        $sys_info['curent_version'] = $upgradeLogic->curent_version; //当前程序版本
63
+        $sys_info['web_name'] = !empty($globalTpCache['web_name']) ? $globalTpCache['web_name'] : '';
64
+        $this->assign('sys_info', $sys_info);
65
+
66
+        $upgradeMsg = $upgradeLogic->checkVersion(); //升级包消息     
67
+        $this->assign('upgradeMsg',$upgradeMsg);
68
+
69
+        if (isset($globalTpCache['web_show_popup_upgrade']) && 2 == $globalTpCache['web_show_popup_upgrade'] && $this->php_servicemeal <= 0) {
70
+            $globalTpCache['web_show_popup_upgrade'] = -1;
71
+        }
72
+        $this->assign('web_show_popup_upgrade', $globalTpCache['web_show_popup_upgrade']);
73
+
74
+        $this->assign('global', $globalTpCache);
75
+
76
+        return $this->fetch();
77
+    }
78
+
79
+    /**
80
+    * 一键升级
81
+    */
82
+    public function OneKeyUpgrade(){
83
+        header('Content-Type:application/json; charset=utf-8');
84
+        function_exists('set_time_limit') && set_time_limit(0);
85
+
86
+        /*权限控制 by 小虎哥*/
87
+        $admin_info = session('admin_info');
88
+        if (0 < intval($admin_info['role_id'])) {
89
+            $auth_role_info = $admin_info['auth_role_info'];
90
+            if (!empty($auth_role_info) && intval($auth_role_info['online_update']) <= 0) {
91
+                $this->error('您没有操作权限,请联系超级管理员分配权限');
92
+            }
93
+        }
94
+        /*--end*/
95
+
96
+        $curent_version = getCmsVersion();
97
+        $upgradeLogic = new \app\admin\logic\UpgradeLogic();
98
+        $data = $upgradeLogic->OneKeyUpgrade(); //升级包消息
99
+        if (1 <= intval($data['code'])) {
100
+            adminLog("系统在线升级:{$curent_version} -> ".getCmsVersion());
101
+            $this->success($data['msg'], null, ['code'=>$data['code']]);
102
+        } else {
103
+            $code = 0;
104
+            $msg = '升级异常,请排查问题!';
105
+            if (is_array($data)) {
106
+                isset($data['code']) && $code = $data['code'];
107
+                isset($data['msg']) && $msg = $data['msg'];
108
+            }
109
+            $this->error($msg, null, ['code'=>$code]);
110
+        }
111
+    }
112
+
113
+    /**
114
+    * 设置弹窗更新-不再提醒
115
+    */
116
+    public function setPopupUpgrade()
117
+    {
118
+        $show_popup_upgrade = input('param.show_popup_upgrade/s', '1');
119
+        $inc_type = 'web';
120
+        tpCache($inc_type, array($inc_type.'_show_popup_upgrade'=>$show_popup_upgrade));
121
+        respose(1);
122
+    }
123
+
124
+    /**
125
+    * 检测目录权限、当前版本的数据库是否与官方一致
126
+    */
127
+    public function check_authority()
128
+    {
129
+        /*------------------检测目录读写权限----------------------*/
130
+        $filelist = tpCache('system.system_upgrade_filelist');
131
+        $filelist = base64_decode($filelist);
132
+        $filelist = htmlspecialchars_decode($filelist);
133
+        $filelist = explode('<br>', $filelist);
134
+        $dirs = array();
135
+        $i = -1;
136
+        foreach($filelist as $filename)
137
+        {
138
+            $tfilename = $filename;
139
+            $curdir = $this->GetDirName($tfilename);
140
+            if (empty($curdir) || !file_exists($curdir)) {
141
+                continue;
142
+            }
143
+            if( !isset($dirs[$curdir]) ) 
144
+            {
145
+                $dirs[$curdir] = $this->TestIsFileDir($curdir);
146
+            }
147
+            if($dirs[$curdir]['isdir'] == FALSE) 
148
+            {
149
+                continue;
150
+            }
151
+            else {
152
+                @tp_mkdir($curdir, 0777);
153
+                $dirs[$curdir] = $this->TestIsFileDir($curdir);
154
+            }
155
+            $i++;
156
+        }
157
+
158
+        $is_pass = true;
159
+        $msg = '检测通过';
160
+        if($i > -1)
161
+        {
162
+            $n = 0;
163
+            $dirinfos = '';
164
+            foreach($dirs as $curdir)
165
+            {
166
+                $dirinfos .= $curdir['name']."&nbsp;&nbsp;状态:";
167
+                if ($curdir['writeable']) {
168
+                    $dirinfos .= "[√正常]";
169
+                } else {
170
+                    $is_pass = false;
171
+                    $n++;
172
+                    $dirinfos .= "<font color='red'>[×不可写]</font>";
173
+                }
174
+                $dirinfos .= "<br />";
175
+            }
176
+            $title = "本次升级需要在下面文件夹写入更新文件,已检测站点有 <font color='red'>{$n}</font> 处没有写入权限:<br />";
177
+            $title .= "<font color='red'>问题分析(如有问题,请咨询技术支持):<br />";
178
+            $title .= "1、检查站点目录的用户组与所有者,禁止是 root ;<br />";
179
+            $title .= "2、检查站点目录的读写权限,一般权限值是 0755 ;<br />";
180
+            $title .= "</font>涉及更新目录列表如下:<br />";
181
+            $msg = $title . $dirinfos;
182
+        }
183
+        /*------------------end----------------------*/
184
+
185
+        if (true == $is_pass) {
186
+            /*------------------检测目录读写权限----------------------*/
187
+            $values = [
188
+                'version' => getCmsVersion(),
189
+            ];
190
+            $upgradeLogic = new \app\admin\logic\UpgradeLogic;
191
+            $upgradeLogic->GetKeyData($values);
192
+            $url = $upgradeLogic->getServiceUrl().'/index.php?m=api&c=Service&a=get_database_txt';
193
+            $response = @httpRequest($url, 'POST', $values, [], 5);
194
+            if (false === $response) {
195
+                $url = $url.'&'.http_build_query($values);
196
+                $context = stream_context_set_default(array('http' => array('timeout' => 5,'method'=>'GET')));
197
+                $response = @file_get_contents($url, false, $context);
198
+            }
199
+            $params = json_decode($response,true);
200
+            if (false == $params) {
201
+                $this->error('连接升级服务器超时,请刷新重试!', null, ['code'=>2]);
202
+            }
203
+
204
+            if (is_array($params)) {
205
+                if (1 == intval($params['code'])) {
206
+                    /*------------------组合本地数据库信息----------------------*/
207
+                    $dbtables = Db::query('SHOW TABLE STATUS');
208
+                    $local_database = array();
209
+                    foreach ($dbtables as $k => $v) {
210
+                        $table = $v['Name'];
211
+                        if (preg_match('/^'.PREFIX.'/i', $table)) {
212
+                            $local_database[$table] = [
213
+                                'name'  => $table,
214
+                                'field' => [],
215
+                            ];
216
+                        }
217
+                    }
218
+                    /*------------------end----------------------*/
219
+
220
+                    /*------------------组合官方远程数据库信息----------------------*/
221
+                    $info = $params['info'];
222
+                    $info = preg_replace("#[\r\n]{1,}#", "\n", $info);
223
+                    $infos = explode("\n", $info);
224
+                    $infolists = [];
225
+                    foreach ($infos as $key => $val) {
226
+                        if (!empty($val)) {
227
+                            $arr = explode('|', $val);
228
+                            $infolists[$arr[0]] = $val;
229
+                        }
230
+                    }
231
+                    /*------------------end----------------------*/
232
+
233
+                    /*------------------校验数据库是否合格----------------------*/
234
+                    foreach ([1] as $testk => $testv) {
235
+                        // 对比数据表数量
236
+                        if (count($local_database) < count($infolists)) {
237
+                            $is_pass = false;
238
+                            break;
239
+                        }
240
+
241
+                        // 对比数据表字段数量
242
+                        foreach ($infolists as $k1 => $v1) {
243
+                            $arr1 = explode('|', $v1);
244
+                            
245
+                            if (1 >= count($arr1)) {
246
+                                continue; // 忽略不对比的数据表
247
+                            }
248
+
249
+                            $fieldArr = explode(',', $arr1[1]);
250
+                            $table = preg_replace('/^ey_/i', PREFIX, $arr1[0]);
251
+                            $local_fields = Db::getFields($table); // 本地数据表字段列表
252
+                            $local_database[$table]['field'] = $local_fields;
253
+                            if (count($local_fields) < count($fieldArr)) {
254
+                                $is_pass = false;
255
+                                break;
256
+                            }
257
+                        }
258
+                        if (false == $is_pass) break;
259
+                    }
260
+                    /*------------------end----------------------*/
261
+                } else if (2 == intval($params['code'])) {
262
+                    $this->error('官方缺少版本号'.getCmsVersion().'的数据库比较文件!', null, ['code'=>2]);
263
+                }
264
+            }
265
+
266
+            if (true == $is_pass) {
267
+                $this->success($msg);
268
+            } else {
269
+                $this->error('当前数据库结构与官方不一致,请查看官方解决教程!', null, ['code'=>2]);
270
+            }
271
+            /*------------------end----------------------*/
272
+        } else {
273
+            $this->error($msg, null, ['code'=>1]);
274
+        }
275
+    }
276
+
277
+    /**
278
+     * 获取文件的目录路径
279
+     * @param string $filename 文件路径+文件名
280
+     * @return string
281
+     */
282
+    private function GetDirName($filename)
283
+    {
284
+        $dirname = preg_replace("#[\\\\\/]{1,}#", '/', $filename);
285
+        $dirname = preg_replace("#([^\/]*)$#", '', $dirname);
286
+        $dirname = preg_replace('/^data\/backup\/tpl\//i', '', $dirname);
287
+        return $dirname;
288
+    }
289
+
290
+    /**
291
+     * 测试目录路径是否有读写权限
292
+     * @param string $dirname 文件目录路径
293
+     * @return array
294
+     */
295
+    private function TestIsFileDir($dirname)
296
+    {
297
+        $dirs = array('name'=>'', 'isdir'=>FALSE, 'writeable'=>FALSE);
298
+        $dirs['name'] =  $dirname;
299
+        tp_mkdir($dirname);
300
+        if(is_dir($dirname))
301
+        {
302
+            $dirs['isdir'] = TRUE;
303
+            $dirs['writeable'] = $this->TestWriteAble($dirname);
304
+        }
305
+        return $dirs;
306
+    }
307
+
308
+    /**
309
+     * 测试目录路径是否有写入权限
310
+     * @param string $d 目录路劲
311
+     * @return boolean
312
+     */
313
+    private function TestWriteAble($d)
314
+    {
315
+        $tfile = '_eyout.txt';
316
+        $fp = @fopen($d.$tfile,'w');
317
+        if(!$fp) {
318
+            if (@is_writable($d)) {
319
+                return true;
320
+            }
321
+            return false;
322
+        }
323
+        else {
324
+            fclose($fp);
325
+            $rs = @unlink($d.$tfile);
326
+            return true;
327
+        }
328
+    }
329
+}

+ 630
- 0
application/admin/controller/Uploadify.php View File

@@ -0,0 +1,630 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3 
12
+ */
13
+ 
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+
18
+class Uploadify extends Base
19
+{
20
+    public $image_type = '';
21
+    private $imageExt = '';
22
+    private $image_accept = '';
23
+
24
+    /**
25
+     * 析构函数
26
+     */
27
+    function __construct() 
28
+    {
29
+        parent::__construct();
30
+        $this->imageExt = config('global.image_ext');
31
+        $this->image_type = tpCache('basic.image_type');
32
+        $this->image_type = !empty($this->image_type) ? str_replace('|', ',', $this->image_type) : $this->imageExt;
33
+        $this->image_accept = image_accept_arr($this->image_type);
34
+    }
35
+
36
+    /**
37
+     * 通用的上传图片
38
+     */
39
+    public function upload()
40
+    {
41
+        $func = input('func');
42
+        $path = input('path','allimg');
43
+        $num  = input('num/d', '1');
44
+        $is_water  = input('is_water/d', 1);
45
+        $default_size = intval(tpCache('basic.file_size') * 1024 * 1024); // 单位为b
46
+        $size = input('size/d'); // 单位为kb
47
+        $size = empty($size) ? $default_size : $size*1024;
48
+        $info = array(
49
+            'num'      => $num,
50
+            'title'    => '',          
51
+            'upload'   => url('Ueditor/imageUp',array('savepath'=>$path,'pictitle'=>'banner','dir'=>'images','is_water'=>$is_water)),
52
+            'fileList' => url('Uploadify/fileList',array('path'=>$path)),
53
+            'size'     => $size,
54
+            'type'     => $this->image_type,
55
+            'input'    => input('input'),
56
+            'func'     => empty($func) ? 'undefined' : $func,
57
+            'path'     => $path,
58
+        );
59
+        $this->assign('info',$info);
60
+        return $this->fetch();
61
+    }
62
+
63
+    /**
64
+     * 图库在线管理 - 左侧树形目录结构
65
+     */
66
+    public function picture_folder()
67
+    {   
68
+        $func = input('func');
69
+        $path = input('path','allimg');
70
+        $num  = input('num/d', '1');
71
+        $default_size = intval(tpCache('basic.file_size') * 1024 * 1024); // 单位为b
72
+        $size = input('size/d'); // 单位为kb
73
+        $size = empty($size) ? $default_size : $size*1024;
74
+        $info = array(
75
+            'num'      => $num,
76
+            'title'    => '',          
77
+            'upload'   => url('Ueditor/imageUp',array('savepath'=>$path,'pictitle'=>'banner','dir'=>'images')),
78
+            'fileList' => url('Uploadify/fileList',array('path'=>$path)),
79
+            'size'     => $size,
80
+            'type'     => $this->image_type,
81
+            'input'    => input('input'),
82
+            'func'     => empty($func) ? 'undefined' : $func,
83
+            'path'     => $path,
84
+        );
85
+        $this->assign('info',$info);
86
+
87
+        // 侧边栏目录栏目
88
+        $dirArr  = $this->getDir('uploads');
89
+        $dirArr2 = [];
90
+        foreach ($dirArr as $key => $val) {
91
+            $dirArr2[$val['id']] = $val['dirpath'];
92
+        }
93
+        foreach ($dirArr as $key => $val) {
94
+            $dirfileArr = glob("{$val['dirpath']}/*");
95
+            if (empty($dirfileArr)) {
96
+                empty($dirfileArr) && @rmdir($val['dirpath']);
97
+                $dirArr[$key] = [];
98
+                continue;
99
+            }
100
+            /*图库显示数量*/
101
+            $countFile = 0;
102
+            $dirfileArr2 = glob("{$val['dirpath']}/*.*"); // 文件数量
103
+            $countFile = count($dirfileArr2);
104
+            /*end*/
105
+            $dirname = preg_replace('/([^\/]+)$/i', '', $val['dirpath']);
106
+            $arr_key = array_search(trim($dirname, '/'), $dirArr2);
107
+            if (!empty($arr_key)) {
108
+                $dirArr[$key]['pId'] = $arr_key;
109
+            } else {
110
+                $dirArr[$key]['pId'] = 0;
111
+            }
112
+            $dirArr[$key]['name'] = preg_replace('/^(.*)\/([^\/]+)$/i', '${2}', $val['dirpath']);
113
+            !empty($countFile) && $dirArr[$key]['name'] .= "({$countFile})"; // 图库显示数量
114
+        }
115
+
116
+        $zNodes = json_encode($dirArr,true);
117
+        $this->assign('zNodes', $zNodes);
118
+        return $this->fetch();
119
+    }
120
+
121
+    /**
122
+     * 图库在线管理 - 图片列表显示
123
+     */
124
+    public function get_images_path($images_path = 'uploads')
125
+    {
126
+       if ('uploads' != $images_path && !preg_match('#^(uploads)/(.*)$#i', $images_path)) {
127
+            $this->error('非法访问!');
128
+        }
129
+
130
+        $func = input('func/s');
131
+        $num  = input('num/d', '1');
132
+        $info = array(
133
+            'num'  => $num,
134
+            'func' => empty($func) ? 'undefined' : $func,
135
+        );
136
+        $this->assign('info',$info);
137
+
138
+        // 常用图片
139
+        $common_pic = [];
140
+        $arr1 = explode('/', $images_path);
141
+        if (1 >= count($arr1)) { // 只有一级目录才显示常用图片
142
+            $where = [
143
+                'lang' => $this->admin_lang,
144
+            ];
145
+            $common_pic = Db::name('common_pic')->where($where)->order('id desc')->limit(6)->field('pic_path')->select();
146
+        }
147
+        $this->assign('common_pic', $common_pic);
148
+
149
+        // 图片列表
150
+        $images_data = glob($images_path.'/*');
151
+        $list = [];
152
+        if (!empty($images_data)) {
153
+            // 图片类型数组
154
+            $image_ext = explode(',', $this->imageExt);
155
+            // 处理图片
156
+            foreach ($images_data as $key => $file) {
157
+                $fileArr = explode('.', $file);    
158
+                $ext = end($fileArr);
159
+                $ext = strtolower($ext);
160
+                if (in_array($ext, $image_ext)) {
161
+                    $list[$key]['path'] = ROOT_DIR.'/'.$file;
162
+                    $list[$key]['time'] = @filemtime($file);
163
+                }
164
+            }
165
+        }
166
+        
167
+        // 图片选择的时间从大到小排序
168
+        $list_time = get_arr_column($list,'time');
169
+        array_multisort($list_time,SORT_DESC,$list);
170
+        // 返回数据
171
+        $this->assign('list', $list);
172
+
173
+        $this->assign('path_directory', $images_path);
174
+
175
+        return $this->fetch();
176
+    }
177
+
178
+    /**
179
+     * 记录常用图片
180
+     */
181
+    public function update_pic()
182
+    {
183
+        if(IS_AJAX_POST){
184
+            $param = input('param.');
185
+            if (!empty($param['images_array'])) {
186
+                $images_array = $param['images_array'];
187
+                $commonPic_db = Db::name('common_pic');
188
+                $data  = [];
189
+                foreach ($images_array as $key => $value) {
190
+                    // 添加数组
191
+                    $data[$key] = [
192
+                        'pic_path'    => $value,
193
+                        'lang'        => $this->admin_lang,
194
+                        'add_time'    => getTime(),
195
+                        'update_time' => getTime(),
196
+                    ];
197
+                }
198
+
199
+                // 批量删除选中的图片
200
+                $commonPic_db->where('pic_path','IN',$images_array)->delete();
201
+
202
+                // 批量添加图片
203
+                !empty($data) && $commonPic_db->insertAll($data);
204
+
205
+                // 查询最后一条数据
206
+                $row = $commonPic_db->order('id desc')->limit('20,1')->field('id')->select();
207
+                if (!empty($row)) {
208
+                    $id = $row[0]['id'];
209
+                    // 删除ID往后的数据
210
+                    $where_ = array(
211
+                        'id'   => array('<',$id),
212
+                        'lang' => $this->admin_lang,
213
+                    );
214
+                    $commonPic_db->where($where_)->delete();
215
+                }
216
+            }
217
+        }
218
+    }
219
+
220
+    /**
221
+     * 在弹出窗里的上传图片
222
+     */
223
+    public function upload_frame()
224
+    {
225
+        $func = input('func');
226
+        $path = input('path','allimg');
227
+        $num = input('num/d', '1');
228
+        $default_size = intval(tpCache('basic.file_size') * 1024 * 1024); // 单位为b
229
+        $size = input('size/d'); // 单位为kb
230
+        $size = empty($size) ? $default_size : $size*1024;
231
+        $info = array(
232
+            'num'=> $num,
233
+            'title' => '',          
234
+            'upload' =>url('Ueditor/imageUp',array('savepath'=>$path,'pictitle'=>'banner','dir'=>'images')),
235
+            'fileList'=>url('Uploadify/fileList',array('path'=>$path)),
236
+            'size' => $size,
237
+            'type' => $this->image_type,
238
+            'input' => input('input'),
239
+            'func' => empty($func) ? 'undefined' : $func,
240
+            'path'     => $path,
241
+        );
242
+        $this->assign('info',$info);
243
+        return $this->fetch();
244
+    }
245
+
246
+    /**
247
+     * 后台(产品)专用
248
+     */
249
+    public function upload_product()
250
+    {
251
+        $aid = input('aid/d');
252
+        $func = input('func');
253
+        $path = input('path','allimg');
254
+        $num = input('num/d', '1');
255
+        $default_size = intval(tpCache('basic.file_size') * 1024 * 1024); // 单位为b
256
+        $size = input('size/d'); // 单位为kb
257
+        $size = empty($size) ? $default_size : $size*1024;
258
+        $field = array(
259
+            'aid' => $aid,
260
+            'num' => $num,
261
+            'title' => '',          
262
+            'upload' => url('Ueditor/imageUp',array('savepath'=>$path,'pictitle'=>'banner','dir'=>'images')),
263
+            'fileList'=> url('Uploadify/fileList',array('path'=>$path)),
264
+            'size' => $size,
265
+            'type' => $this->image_type,
266
+            'input' => input('input'),
267
+            'func' => empty($func) ? 'undefined' : $func,
268
+            'path'     => $path,
269
+        );
270
+        $this->assign('field',$field);
271
+        return $this->fetch();
272
+    }
273
+
274
+    /**
275
+     * 完整的上传模板展示
276
+     */
277
+    public function upload_full()
278
+    {
279
+        $func = input('func');
280
+        $path = input('path','allimg');
281
+        $num = input('num/d', '1');
282
+        $default_size = intval(tpCache('basic.file_size') * 1024 * 1024); // 单位为b
283
+        $size = input('size/d'); // 单位为kb
284
+        $size = empty($size) ? $default_size : $size*1024;
285
+        $info = array(
286
+            'num'=> $num,
287
+            'title' => '',          
288
+            'upload' =>url('Ueditor/imageUp',array('savepath'=>$path,'pictitle'=>'banner','dir'=>'images')),
289
+            'fileList'=>url('Uploadify/fileList',array('path'=>$path)),
290
+            'size' => $size,
291
+            'type' => $this->image_type,
292
+            'input' => input('input'),
293
+            'func' => empty($func) ? 'undefined' : $func,
294
+            'path'     => $path,
295
+        );
296
+        $this->assign('info',$info);
297
+        return $this->fetch();
298
+    }
299
+    
300
+    /*
301
+     * 删除上传的图片
302
+     */
303
+    public function delupload()
304
+    {
305
+        echo 1;
306
+        exit;
307
+            
308
+        if (IS_POST) {
309
+            $action = input('action','del');  
310
+            $filename= input('filename/s');
311
+            $filename= empty($filename) ? input('url') : $filename;
312
+            $filename= str_replace(['(',')',',',' ','../','..','./'],'',$filename);
313
+            $filename= trim($filename,'.');
314
+            $filename = preg_replace('#^(/[/\w\-]+)?(/public/upload/|/uploads/|/public/static/admin/logo/)#i', '$2', $filename);
315
+            if(eyPreventShell($filename) && $action=='del' && !empty($filename) && is_file('.'.$filename) && stristr($filename, 'uploads/')){
316
+                if (stristr($filename, '/admin/logo/')) {
317
+                    $filetype = preg_replace('/^(.*)\.(\w+)$/i', '$2', $filename);
318
+                    $phpfile = strtolower(strstr($filename,'.php'));  //排除PHP文件
319
+                    $size = getimagesize('.'.$filename);
320
+                    $fileInfo = explode('/',$size['mime']);
321
+                    if($fileInfo[0] != 'image' || $phpfile || !in_array($filetype, explode(',', $this->imageExt))){
322
+                        exit;
323
+                    }
324
+                    if(@unlink('.'.$filename)){
325
+                        echo 1;
326
+                    }else{
327
+                        echo 0;
328
+                    }  
329
+                    exit;
330
+                }
331
+            }
332
+
333
+            echo 1;
334
+            exit;
335
+        }
336
+    }
337
+    
338
+    public function fileList(){
339
+        /* 判断类型 */
340
+        $type = input('type','Images');
341
+        switch ($type){
342
+            /* 列出图片 */
343
+            case 'Images' : $allowFiles = str_replace(',', '|', $this->image_type);break;
344
+        
345
+            case 'Flash' : $allowFiles = 'flash|swf';break;
346
+        
347
+            /* 列出文件 */
348
+            default : 
349
+            {
350
+                $file_type = tpCache('basic.file_type');
351
+                $media_type = tpCache('basic.media_type');
352
+                $allowFiles = $file_type.'|'.$media_type;
353
+            }
354
+        }
355
+
356
+        $listSize = 102400000;
357
+        
358
+        $key = empty($_GET['key']) ? '' : $_GET['key'];
359
+        
360
+        /* 获取参数 */
361
+        $size = isset($_GET['size']) ? htmlspecialchars($_GET['size']) : $listSize;
362
+        $start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0;
363
+        $end = $start + $size;
364
+        
365
+        $path = input('path','allimg');
366
+        if (1 == preg_match('#\.#', $path)) {
367
+            echo json_encode(array(
368
+                    "state" => "路径不符合规范",
369
+                    "list" => array(),
370
+                    "start" => $start,
371
+                    "total" => 0
372
+            ));
373
+            exit;
374
+        }
375
+        if ('adminlogo' == $path) {
376
+            $path = 'public/static/admin/logo';
377
+        } else if ('loginlogo' == $path) {
378
+            $path = 'public/static/admin/login';
379
+        } else if ('loginbgimg' == $path) {
380
+            $path = 'public/static/admin/loginbg';
381
+        } else {
382
+            $path = UPLOAD_PATH.$path;
383
+        }
384
+
385
+        /* 获取文件列表 */
386
+        $files = $this->getfiles($path, $allowFiles, $key);
387
+        if (empty($files)) {
388
+            echo json_encode(array(
389
+                    "state" => "没有相关文件",
390
+                    "list" => array(),
391
+                    "start" => $start,
392
+                    "total" => count($files)
393
+            ));
394
+            exit;
395
+        }
396
+        
397
+        /* 获取指定范围的列表 */
398
+        $len = count($files);
399
+        for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
400
+            $list[] = $files[$i];
401
+        }
402
+        
403
+        /* 返回数据 */
404
+        $result = json_encode(array(
405
+                "state" => "SUCCESS",
406
+                "list" => $list,
407
+                "start" => $start,
408
+                "total" => count($files)
409
+        ));
410
+        
411
+        echo $result;
412
+    }
413
+
414
+    /**
415
+     * 遍历获取目录下的指定类型的文件
416
+     * @param $path
417
+     * @param array $files
418
+     * @return array
419
+     */
420
+    private function getfiles($path, $allowFiles, $key, &$files = array()){
421
+        if (!is_dir($path)) return null;
422
+        if(substr($path, strlen($path) - 1) != '/') $path .= '/';
423
+        $handle = opendir($path);
424
+        while (false !== ($file = readdir($handle))) {
425
+            if ($file != '.' && $file != '..') {
426
+                $path2 = $path . $file;
427
+                if (is_dir($path2)) {
428
+                    $this->getfiles($path2, $allowFiles, $key, $files);
429
+                } else {
430
+                    if (preg_match("/\.(".$allowFiles.")$/i", $file) && preg_match("/.*". $key .".*/i", $file)) {
431
+                        $files[] = array(
432
+                            'url'=> ROOT_DIR.'/'.$path2, // 支持子目录
433
+                            'name'=> $file,
434
+                            'mtime'=> filemtime($path2)
435
+                        );
436
+                    }
437
+                }
438
+            }
439
+        }
440
+        return $files;
441
+    }
442
+
443
+    /**
444
+     * 提取上传图片目录下的所有图片
445
+     *
446
+     * @param string $directory 目录路径
447
+     * @param string $dir_name 显示的目录前缀路径
448
+     * @param array $arr_file 是否删除空目录
449
+     * @param num $num 数量
450
+     */
451
+    private function getDir($directory, &$arr_file = array(), &$num = 0) {
452
+        $mydir = glob($directory.'/*', GLOB_ONLYDIR);
453
+        $param = input('param.');
454
+        if (0 <= $num) {
455
+            $dirpathArr = explode('/', $directory);
456
+            $level = count($dirpathArr);
457
+            $open = (1 >= $level) ? true : false;
458
+            $fileList = glob($directory.'/*');
459
+            $total = count($fileList); // 目录是否存在任意文件,否则删除该目录
460
+            if (!empty($total)) {
461
+                $isExistPic = $this->isExistPic($directory);
462
+                if (!empty($isExistPic)) {
463
+                    $arr_file[] = [
464
+                        'id'        => $num,
465
+                        'url'       => url('Uploadify/get_images_path',['num'=>$param['num'],'func'=>$param['func'],'lang'=>$param['lang'],'images_path'=>$directory]),
466
+                        'target'    => 'content_body',
467
+                        'isParent'  => true,
468
+                        'open'      => $open,
469
+                        'dirpath'   => $directory,
470
+                        'level'     => $level,
471
+                        'total'     => $total,
472
+                    ];
473
+                }
474
+            } else {
475
+                @rmdir("$directory");
476
+            }
477
+        }
478
+        if (!empty($mydir)) {
479
+            foreach ($mydir as $key => $dir) {
480
+                if (stristr("$dir/", 'uploads/soft_tmp/') || stristr("$dir/", 'uploads/tmp/')) {
481
+                    continue;
482
+                }
483
+                $num++;
484
+                $dirname = str_replace('\\', '/', $dir);
485
+                $dirArr  = explode('/', $dirname);
486
+                $dir     = end($dirArr);
487
+                $mydir2  = glob("$directory/$dir/*", GLOB_ONLYDIR);
488
+                if(!empty($mydir2) AND ($dir != ".") AND ($dir != ".."))
489
+                {
490
+                    $this->getDir("$directory/$dir", $arr_file, $num);
491
+                }
492
+                else if(($dir != ".") AND ($dir != ".."))
493
+                {
494
+                    $dirpathArr = explode('/', "$directory/$dir");
495
+                    $level = count($dirpathArr);
496
+                    $fileList = glob("$directory/$dir/*"); // 目录是否存在任意文件,否则删除该目录
497
+                    $total = count($fileList);
498
+                    if (!empty($total)) {
499
+                         // 目录是否存在图片文件,否则删除该目录
500
+                        $isExistPic = $this->isExistPic("$directory/$dir");
501
+                        if (!empty($isExistPic)) {
502
+                            $arr_file[] = [
503
+                                'id'        => $num,
504
+                                'url'       => url('Uploadify/get_images_path',['num'=>$param['num'],'func'=>$param['func'],'lang'=>$param['lang'],'images_path'=>"$directory/$dir"]),
505
+                                'target'    => 'content_body',
506
+                                'isParent'  => false,
507
+                                'open'      => false,
508
+                                'dirpath'   => "$directory/$dir",
509
+                                'level'     => $level,
510
+                                'icon'      => 'public/plugins/ztree/css/zTreeStyle/img/dir_close.png',
511
+                                'iconOpen'  => 'public/plugins/ztree/css/zTreeStyle/img/dir_open.png',
512
+                                'iconClose' => 'public/plugins/ztree/css/zTreeStyle/img/dir_close.png',
513
+                                'total'     => $total,
514
+                            ];
515
+                        }
516
+                    } else {
517
+                        @rmdir("$directory/$dir");
518
+                    }
519
+                }
520
+            }
521
+        }
522
+        return $arr_file;
523
+    }
524
+
525
+    /**
526
+     * 检测指定目录是否存在图片
527
+     *
528
+     * @param string $directory 目录路径
529
+     * @param string $dir_name 显示的目录前缀路径
530
+     * @param array $arr_file 是否删除空目录
531
+     * @return boolean
532
+     */
533
+    private function isExistPic($directory, $dir_name='', &$arr_file = [])
534
+    {
535
+        if (!file_exists($directory) ) {
536
+            return false;
537
+        }
538
+
539
+        if (!empty($arr_file)) {
540
+            return true;
541
+        }
542
+
543
+        // 图片类型数组
544
+        $image_ext = explode(',', $this->imageExt);
545
+        $mydir = dir($directory);
546
+        while($file = $mydir->read())
547
+        {
548
+            if((is_dir("$directory/$file")) AND ($file != ".") AND ($file != ".."))
549
+            {
550
+                if ($dir_name) {
551
+                    return $this->isExistPic("$directory/$file", "$dir_name/$file", $arr_file);
552
+                } else {
553
+                    return $this->isExistPic("$directory/$file", "$file", $arr_file);
554
+                }
555
+                
556
+            }
557
+            else if(($file != ".") AND ($file != ".."))
558
+            {
559
+                $fileArr = explode('.', $file);    
560
+                $ext = end($fileArr);
561
+                $ext = strtolower($ext);
562
+                if (in_array($ext, $image_ext)) {
563
+                    if ($dir_name) {
564
+                        $arr_file[] = "$dir_name/$file";
565
+                    } else {
566
+                        $arr_file[] = "$file";
567
+                    }
568
+                    return true;
569
+                }
570
+
571
+            }
572
+        }
573
+        $mydir->close();
574
+
575
+        return $arr_file;
576
+    }
577
+
578
+    /**
579
+     * 未开启同步本地功能,并删除本地图片
580
+     * @return [type] [description]
581
+     */
582
+    public function del_local()
583
+    {
584
+        if (IS_AJAX_POST) {
585
+            \think\Session::pause(); // 暂停session,防止session阻塞机制
586
+            $post = input('post.');
587
+            $filename = '';
588
+            if (!empty($post['filename'])) {
589
+                if (is_array($post['filename'])) {
590
+                    $filename = $post['filename'][0];
591
+                } else {
592
+                    $filename = $post['filename'];
593
+                }
594
+            }
595
+            $filename = strstr($filename, "/uploads/");
596
+            if (!empty($filename)){
597
+                $weappList = Db::name('weapp')->where([
598
+                    'status'    => 1,
599
+                ])->cache(true, EYOUCMS_CACHE_TIME, 'weapp')
600
+                ->getAllWithIndex('code');
601
+
602
+                if (!empty($weappList['Qiniuyun']) && 1 == $weappList['Qiniuyun']['status']) {
603
+                    $weappConfig = json_decode($weappList['Qiniuyun']['config'], true);
604
+                    if (!empty($weappConfig['version']) && 'v1.0.9' <= $weappConfig['version']) {
605
+                        $qnyData = json_decode($weappList['Qiniuyun']['data'], true);
606
+                        if (!empty($qnyData['local_save']) && $qnyData['local_save'] == 1) {
607
+                            $qiniuyunOssModel = new \weapp\Qiniuyun\model\QiniuyunModel;
608
+                            $qiniuyunOssModel->del_local($filename);
609
+                        }
610
+                    }
611
+                } else if (!empty($weappList['AliyunOss']) && 1 == $weappList['AliyunOss']['status']) {
612
+                    $weappConfig = json_decode($weappList['AliyunOss']['config'], true);
613
+                    if (!empty($weappConfig['version']) && 'v1.0.2' <= $weappConfig['version']) {
614
+                        $ossData = json_decode($weappList['AliyunOss']['data'], true);
615
+                        if (!empty($ossData['local_save']) && $ossData['local_save'] == 1) {
616
+                            $aliyunOssModel = new \weapp\AliyunOss\model\AliyunOssModel;
617
+                            $aliyunOssModel->del_local($filename);
618
+                        }
619
+                    }
620
+                } else if (!empty($weappList['Cos']) && 1 == $weappList['Cos']['status']) {
621
+                    $cosData = json_decode($weappList['Cos']['data'], true);
622
+                    if (!empty($cosData['local_save']) && $cosData['local_save'] == 1) {
623
+                        $cosModel = new \weapp\Cos\model\CosModel;
624
+                        $cosModel->del_local($filename);
625
+                    }
626
+                }
627
+            }
628
+        }
629
+    }
630
+}

+ 792
- 0
application/admin/controller/Uploadimgnew.php View File

@@ -0,0 +1,792 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3 
12
+ */
13
+ 
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+
19
+class Uploadimgnew extends Base
20
+{
21
+    public $image_type = '';
22
+    private $imageExt = '';
23
+    private $php_sessid = '';
24
+    private $image_accept = '';
25
+
26
+    /**
27
+     * 析构函数
28
+     */
29
+    function __construct() 
30
+    {
31
+        parent::__construct();
32
+        $this->imageExt = config('global.image_ext');
33
+        $this->image_type = tpCache('basic.image_type');
34
+        $this->image_type = !empty($this->image_type) ? str_replace('|', ',', $this->image_type) : $this->imageExt;
35
+        $this->image_accept = image_accept_arr($this->image_type);
36
+        $this->php_sessid = !empty($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : '';
37
+    }
38
+
39
+    /**
40
+     * 通用的上传图片
41
+     */
42
+    public function upload()
43
+    {
44
+        $assign_data = [];
45
+        $type_id = input('param.type_id/d');
46
+        $assign_data['type_id'] = $type_id;
47
+        // 基础配置 - 附件配置
48
+        $basicConfig = tpCache('basic');
49
+        $assign_data['basicConfig'] = $basicConfig;
50
+
51
+        $func = input('param.func/s', 'undefined');
52
+        $path = input('path','allimg');
53
+        $num  = input('num/d', 1);
54
+        $is_water  = input('is_water/d', 1);
55
+        $default_size = intval($basicConfig['file_size'] * 1024 * 1024); // 单位为b
56
+        $size = input('size/d'); // 单位为kb
57
+        $size = empty($size) ? $default_size : $size*1024;
58
+        $info = array(
59
+            'num'      => $num,
60
+            'size'     => $size,
61
+            'input'    => input('input'),
62
+            'func'     => $func,
63
+            'path'     => $path,
64
+            'is_water' => $is_water,
65
+        );
66
+        $assign_data['info'] = $info;
67
+        $assign_data['default_upload_list_url'] = url('Uploadimgnew/get_upload_list', ['type_id'=>0, 'info'=>base64_encode(json_encode($info))]);
68
+        $assign_data['current_upload_list_url'] = url('Uploadimgnew/get_upload_list', ['type_id'=>$type_id, 'info'=>base64_encode(json_encode($info))]);
69
+
70
+        // 侧边栏我的分组
71
+        $uploads_total_list = Db::name('uploads')->field('type_id, count(img_id) as total')->where(['is_del'=>0])->group('type_id')->getAllWithIndex('type_id');
72
+        $uploads_type_list = Db::name('uploads_type')->order('id asc')->select();
73
+        foreach ($uploads_type_list as $key => $val) {
74
+            $val['total'] = !empty($uploads_total_list[$val['id']]['total']) ? $uploads_total_list[$val['id']]['total'] : 0;
75
+            $val['url'] = url('Uploadimgnew/get_upload_list', ['type_id'=>$val['id'], 'info'=>base64_encode(json_encode($info))]);
76
+            $uploads_type_list[$key] = $val;
77
+        }
78
+        $assign_data['uploads_type_list'] = $uploads_type_list;
79
+        $assign_data['uploads_total_list'] = $uploads_total_list;
80
+
81
+        // 是否已经同步过
82
+        $assign_data['admin_logic_1639031991'] = tpSetting('syn.admin_logic_1639031991', [], 'cn');
83
+
84
+        $this->assign($assign_data);
85
+        return $this->fetch('uploadimgnew/upload');
86
+    }
87
+
88
+    /**
89
+     * 获取左侧树形的目录结构
90
+     * @return [type] [description]
91
+     */
92
+    public function ajax_get_treedir()
93
+    {
94
+        // 侧边栏图片目录
95
+        $dirArr  = $this->getDirImg('uploads');
96
+        $dirArr2 = [];
97
+        foreach ($dirArr as $key => $val) {
98
+            $dirArr2[$val['id']] = $val['dirpath'];
99
+        }
100
+        foreach ($dirArr as $key => $val) {
101
+            $dirfileArr = glob("{$val['dirpath']}/*");
102
+            if (empty($dirfileArr)) {
103
+                empty($dirfileArr) && @rmdir($val['dirpath']);
104
+                $dirArr[$key] = [];
105
+                continue;
106
+            }
107
+            /*图库显示数量*/
108
+            $countFile = 0;
109
+            $image_type_tmp = str_replace(',', '|', $this->image_type);
110
+            foreach ($dirfileArr as $_k => $_v) {
111
+                if (preg_match('/\.('.$image_type_tmp.')$/i', $_v)) {
112
+                    $countFile++;
113
+                }
114
+            }
115
+            /*end*/
116
+            $dirname = preg_replace('/([^\/]+)$/i', '', $val['dirpath']);
117
+            $arr_key = array_search(trim($dirname, '/'), $dirArr2);
118
+            if (!empty($arr_key)) {
119
+                $dirArr[$key]['pId'] = $arr_key;
120
+            } else {
121
+                $dirArr[$key]['pId'] = 0;
122
+            }
123
+            $dirArr[$key]['name'] = preg_replace('/^(.*)\/([^\/]+)$/i', '${2}', $val['dirpath']);
124
+            !empty($countFile) && $dirArr[$key]['name'] .= "({$countFile})"; // 图库显示数量
125
+        }
126
+        $zNodes = json_encode($dirArr,true);
127
+        $this->success('请求成功', null, ['zNodes'=>$zNodes]);
128
+    }
129
+
130
+    /**
131
+     * 右侧上传图片记录的列表显示
132
+     */
133
+    public function get_upload_list()
134
+    {
135
+        $assign_data = [];
136
+
137
+        $type_id = input('param.type_id/d', 0);
138
+        $assign_data['type_id'] = $type_id;
139
+
140
+        $pageNum = input('param.p/d', 1);
141
+        $assign_data['pageNum'] = $pageNum;
142
+
143
+        $info = input('param.info/s');
144
+        $info = json_decode(base64_decode($info), true);
145
+        $info['upload'] = url('Ueditor/imageUp',array('savepath'=>$info['path'],'type_id'=>$type_id,'pictitle'=>'banner','dir'=>'images','is_water'=>$info['is_water']));
146
+        $info['image_accept'] = $this->image_accept;
147
+        $assign_data['info'] = $info;
148
+
149
+        $Where = [];
150
+        // 时间检索条件查询
151
+        $post_eytime = input('eytime/s');
152
+        $EyTime = !empty($post_eytime) ? $post_eytime : '';
153
+        $assign_data['eytime'] = $EyTime;
154
+        if (!empty($EyTime)) {
155
+            $EyTime = explode(' - ', $EyTime);
156
+            // 开始日期
157
+            $Begin = 0;
158
+            if (!empty($EyTime[0])) {
159
+                if (stristr($EyTime[0], ':')) { // 包含了时分秒
160
+                    $Begin = strtotime($EyTime[0]);
161
+                } else {
162
+                    $Begin = strtotime($EyTime[0]." 00:00:00");
163
+                }
164
+            }
165
+            // 结束日期
166
+            $End = 0;
167
+            if (!empty($EyTime[1])) {
168
+                if (stristr($EyTime[1], ':')) { // 包含了时分秒
169
+                    $End = strtotime($EyTime[1]);
170
+                } else {
171
+                    $End = strtotime($EyTime[1]." 23:59:59");
172
+                }
173
+            }
174
+            if ($Begin > 0 && $End > 0) {
175
+                $Where['add_time'] = array('between', "$Begin, $End");
176
+            } else if ($Begin > 0) {
177
+                $Where['add_time'] = array('egt', $Begin);
178
+            } else if ($End > 0) {
179
+                $Where['add_time'] = array('elt', $End);
180
+            }
181
+        }
182
+        $Where['type_id'] = $type_id;
183
+        $Where['is_del'] = 0;
184
+        $countimg = Db::name('uploads')->where($Where)->count('img_id');
185
+        $pageObj = new Page($countimg, 10);
186
+
187
+        // 列表显示
188
+        $imglist = Db::name('uploads')
189
+            ->where($Where)
190
+            ->order('img_id desc')
191
+            ->limit($pageObj->firstRow.','.$pageObj->listRows)
192
+            ->select();
193
+        foreach ($imglist as $key => $val) {
194
+            $val['image_url'] = handle_subdir_pic($val['image_url']);
195
+            empty($val['title']) && $val['title'] = preg_replace('/^(.*)\/([^\/]+)$/i', '${2}', $val['image_url']);
196
+            $imglist[$key] = $val;
197
+        }
198
+        $assign_data['imglist'] = $imglist;
199
+        $assign_data['pageStr'] = $pageObj->show();
200
+
201
+        /*----------------------------第三方存储插件 start------------------------*/
202
+        $storageTitle = '本地服务器';
203
+        $weappList = Db::name('weapp')->where(['status' => 1])
204
+            ->cache(true, EYOUCMS_CACHE_TIME, 'weapp')
205
+            ->getAllWithIndex('code');
206
+        if (!empty($weappList['Qiniuyun']['data'])) {
207
+            $qnyData = json_decode($weappList['Qiniuyun']['data'], true);
208
+            if (!empty($qnyData['bucket'])) {
209
+                $storageTitle = '七牛云';
210
+            }
211
+        } else if (!empty($weappList['AliyunOss']['data'])) {
212
+            $ossData = json_decode($weappList['AliyunOss']['data'], true);
213
+            if (!empty($ossData['bucket'])) {
214
+                $storageTitle = '阿里云OSS';
215
+            }
216
+        } else if (!empty($weappList['Cos']['data'])) {
217
+            $cosData = json_decode($weappList['Cos']['data'], true);
218
+            if (!empty($cosData['secretName'])) {
219
+                $storageTitle = '腾讯云COS';
220
+            }
221
+        }
222
+        $assign_data['storageTitle'] = $storageTitle;
223
+        /*----------------------------第三方存储插件 start------------------------*/
224
+
225
+        // 分组图片总数
226
+        $assign_data['countimg'] = Db::name('uploads')->where(['type_id' => $type_id, 'is_del' => 0])->count('img_id');
227
+
228
+        // 标记是否已经同步导入数据
229
+        $assign_data['admin_logic_1639031991'] = tpSetting('syn.admin_logic_1639031991', [], 'cn');
230
+
231
+        $this->assign($assign_data);
232
+
233
+        return $this->fetch('uploadimgnew/get_upload_list');
234
+    }
235
+
236
+    /**
237
+     * 右侧图片目录的图片列表显示
238
+     */
239
+    public function get_dir_imglist($images_path = 'uploads')
240
+    {
241
+        $assign_data = [];
242
+
243
+        if ('uploads' != $images_path && !preg_match('#^(uploads)/(.*)$#i', $images_path)) {
244
+            $this->error('禁止访问');
245
+        }
246
+
247
+        $num  = input('num/d', 1);
248
+        $info = array(
249
+            'num'  => $num,
250
+        );
251
+        $assign_data['info'] = $info;
252
+
253
+        // 常用图片
254
+        $common_pic = [];
255
+        $arr1 = explode('/', $images_path);
256
+        if (1 >= count($arr1)) { // 只有一级目录才显示常用图片
257
+            $where = [
258
+                'lang' => $this->admin_lang,
259
+            ];
260
+            $common_pic = Db::name('common_pic')->where($where)->order('id desc')->limit(10)->select();
261
+            foreach ($common_pic as $key => $val) {
262
+                $imageInfo = [];
263
+                if (!is_http_url($val['pic_path'])) {
264
+                    $pic_path = handle_subdir_pic($val['pic_path'], 'img', false, true);
265
+                    if (!file_exists('.'.$pic_path)) {
266
+                        unset($common_pic[$key]);
267
+                        continue;
268
+                    }
269
+                    $imageInfo = @getimagesize('.'.$pic_path);
270
+                    $val['pic_path'] = ROOT_DIR.$pic_path;
271
+                }
272
+                $val['title'] = preg_replace('/^(.*)\/([^\/]+)$/i', '${2}', $val['pic_path']);
273
+                $val['width'] = !empty($imageInfo[0]) ? intval($imageInfo[0]) : 0;
274
+                $val['height'] = !empty($imageInfo[1]) ? intval($imageInfo[1]) : 0;
275
+                $common_pic[$key] = $val;
276
+            }
277
+        }
278
+        $assign_data['common_pic'] = $common_pic;
279
+
280
+        // 图片列表
281
+        $list = [];
282
+        $images_data = glob($images_path.'/*');
283
+        if (!empty($images_data)) {
284
+            // 图片类型数组
285
+            $image_ext = explode(',', $this->imageExt);
286
+            // 处理图片
287
+            foreach ($images_data as $key => $file) {
288
+                $fileArr = explode('.', $file);    
289
+                $ext = end($fileArr);
290
+                $ext = strtolower($ext);
291
+                if (in_array($ext, $image_ext)) {
292
+                    $info = [];
293
+                    $imageInfo = @getimagesize('./'.$file);
294
+                    $info['width'] = !empty($imageInfo[0]) ? intval($imageInfo[0]) : 0;
295
+                    $info['height'] = !empty($imageInfo[1]) ? intval($imageInfo[1]) : 0;
296
+                    $info['pic_path'] = ROOT_DIR.'/'.$file;
297
+                    $info['add_time'] = @filemtime($file);
298
+                    empty($info['add_time']) && $info['add_time'] = getTime();
299
+                    $info['title'] = preg_replace('/^(.*)\/([^\/]+)$/i', '${2}', $file);
300
+                    $list[] = $info;
301
+                }
302
+            }
303
+            if (!empty($list)) {
304
+                // 图片选择的时间从大到小排序
305
+                $list_time = get_arr_column($list, 'add_time');
306
+                array_multisort($list_time, SORT_DESC, $list);
307
+            }
308
+        }
309
+
310
+        // 每页显示的图片
311
+        $count = count($list); // 总条数
312
+        $pagesize = 10; // 每页多少条
313
+        $page = input('param.p/d', 1);
314
+        $start = ($page - 1) * $pagesize; // 偏移量,当前页-1乘以每页显示条数
315
+        $list = array_slice($list, $start, $pagesize);
316
+        $assign_data['list'] = $list;
317
+
318
+        // 分页码
319
+        $pageObj = new Page($count, $pagesize);
320
+        $assign_data['pageStr'] = $pageObj->show();
321
+
322
+        $this->assign($assign_data);
323
+
324
+        return $this->fetch('uploadimgnew/get_dir_imglist');
325
+    }
326
+    
327
+    /*
328
+     * 删除上传的图片
329
+     */
330
+    public function delupload()
331
+    {
332
+        echo 1;
333
+        exit;
334
+    }
335
+
336
+    /**
337
+     * 遍历获取目录下的指定类型的文件
338
+     * @param $path
339
+     * @param array $files
340
+     * @return array
341
+     */
342
+    private function getfiles($path, $allowFiles, $key, &$files = array()){
343
+        if (!is_dir($path)) return null;
344
+        if(substr($path, strlen($path) - 1) != '/') $path .= '/';
345
+        $handle = opendir($path);
346
+        while (false !== ($file = readdir($handle))) {
347
+            if ($file != '.' && $file != '..') {
348
+                $path2 = $path . $file;
349
+                if (is_dir($path2)) {
350
+                    $this->getfiles($path2, $allowFiles, $key, $files);
351
+                } else {
352
+                    if (preg_match("/\.(".$allowFiles.")$/i", $file) && preg_match("/.*". $key .".*/i", $file)) {
353
+                        $files[] = array(
354
+                            'url'=> ROOT_DIR.'/'.$path2, // 支持子目录
355
+                            'name'=> $file,
356
+                            'mtime'=> filemtime($path2)
357
+                        );
358
+                    }
359
+                }
360
+            }
361
+        }
362
+        return $files;
363
+    }
364
+
365
+    /**
366
+     * 检测指定目录是否存在图片
367
+     *
368
+     * @param string $directory 目录路径
369
+     * @param string $dir_name 显示的目录前缀路径
370
+     * @param array $arr_file 是否删除空目录
371
+     * @return boolean
372
+     */
373
+    private function isExistPic($directory, $dir_name='', &$arr_file = [])
374
+    {
375
+        if (!file_exists($directory) ) {
376
+            return false;
377
+        }
378
+
379
+        if (!empty($arr_file)) {
380
+            return true;
381
+        }
382
+
383
+        // 图片类型数组
384
+        $image_ext = explode(',', $this->imageExt);
385
+        $mydir = dir($directory);
386
+        while($file = $mydir->read())
387
+        {
388
+            if((is_dir("$directory/$file")) AND ($file != ".") AND ($file != ".."))
389
+            {
390
+                if ($dir_name) {
391
+                    return $this->isExistPic("$directory/$file", "$dir_name/$file", $arr_file);
392
+                } else {
393
+                    return $this->isExistPic("$directory/$file", "$file", $arr_file);
394
+                }
395
+                
396
+            }
397
+            else if(($file != ".") AND ($file != ".."))
398
+            {
399
+                $fileArr = explode('.', $file);    
400
+                $ext = end($fileArr);
401
+                $ext = strtolower($ext);
402
+                if (in_array($ext, $image_ext)) {
403
+                    if ($dir_name) {
404
+                        $arr_file[] = "$dir_name/$file";
405
+                    } else {
406
+                        $arr_file[] = "$file";
407
+                    }
408
+                    return true;
409
+                }
410
+
411
+            }
412
+        }
413
+        $mydir->close();
414
+
415
+        return $arr_file;
416
+    }
417
+
418
+    /**
419
+     * 记录常用图片
420
+     */
421
+    public function update_pic()
422
+    {
423
+        if(IS_AJAX_POST){
424
+            $param = input('param.');
425
+            if (!empty($param['images_array'])) {
426
+                $images_array = $param['images_array'];
427
+                $commonPic_db = Db::name('common_pic');
428
+                $data  = [];
429
+                foreach ($images_array as $key => $value) {
430
+                    // 添加数组
431
+                    $data[$key] = [
432
+                        'pic_path'    => $value,
433
+                        'lang'        => $this->admin_lang,
434
+                        'add_time'    => getTime(),
435
+                        'update_time' => getTime(),
436
+                    ];
437
+                }
438
+
439
+                // 批量删除选中的图片
440
+                $commonPic_db->where('pic_path','IN',$images_array)->delete();
441
+
442
+                // 批量添加图片
443
+                !empty($data) && $commonPic_db->insertAll($data);
444
+
445
+                // 查询最后一条数据
446
+                $row = $commonPic_db->order('id desc')->limit('20,1')->field('id')->select();
447
+                if (!empty($row)) {
448
+                    $id = $row[0]['id'];
449
+                    // 删除ID往后的数据
450
+                    $where_ = array(
451
+                        'id'   => array('<',$id),
452
+                        'lang' => $this->admin_lang,
453
+                    );
454
+                    $commonPic_db->where($where_)->delete();
455
+                }
456
+            }
457
+        }
458
+    }
459
+
460
+    /**
461
+     * 提取上传图片目录下的所有图片
462
+     *
463
+     * @param string $directory 目录路径
464
+     * @param string $dir_name 显示的目录前缀路径
465
+     * @param array $arr_file 是否删除空目录
466
+     * @param num $num 数量
467
+     */
468
+    private function getDirImg($directory, &$arr_file = array(), &$num = 0) {
469
+        $mydir = glob($directory.'/*', GLOB_ONLYDIR);
470
+        $param = input('param.');
471
+        if (0 <= $num) {
472
+            $dirpathArr = explode('/', $directory);
473
+            $level = count($dirpathArr);
474
+            $open = (1 >= $level) ? true : false;
475
+            $fileList = glob("$directory/*");
476
+            $total = count($fileList); // 目录是否存在任意文件,否则删除该目录
477
+            if (!empty($total)) {
478
+                $isExistPic = $this->isExistPic($directory);
479
+                if (!empty($isExistPic)) {
480
+                    $arr_file[] = [
481
+                        'id'        => $num,
482
+                        'url'       => url('Uploadimgnew/get_dir_imglist',['num'=>$param['num'],'lang'=>$this->admin_lang,'images_path'=>$directory]),
483
+                        'target'    => 'content_body',
484
+                        'isParent'  => true,
485
+                        'open'      => $open,
486
+                        'dirpath'   => $directory,
487
+                        'level'     => $level,
488
+                        'total'     => $total,
489
+                    ];
490
+                }
491
+            } else {
492
+                @rmdir("$directory");
493
+            }
494
+        }
495
+        if (!empty($mydir)) {
496
+            foreach ($mydir as $key => $dir) {
497
+                if (preg_match('/uploads\/(soft_tmp|tmp|media|soft)\//i', "$dir/")) {
498
+                    continue;
499
+                }
500
+                $num++;
501
+                $dirname = str_replace('\\', '/', $dir);
502
+                $dirArr  = explode('/', $dirname);
503
+                $dir     = end($dirArr);
504
+                $mydir2  = glob("$directory/$dir/*", GLOB_ONLYDIR);
505
+                if(!empty($mydir2) AND ($dir != ".") AND ($dir != ".."))
506
+                {
507
+                    $this->getDirImg("$directory/$dir", $arr_file, $num);
508
+                }
509
+                else if(($dir != ".") AND ($dir != ".."))
510
+                {
511
+                    $dirpathArr = explode('/', "$directory/$dir");
512
+                    $level = count($dirpathArr);
513
+                    $fileList = glob("$directory/$dir/*"); // 目录是否存在任意文件,否则删除该目录
514
+                    $total = count($fileList);
515
+                    if (!empty($total)) {
516
+                         // 目录是否存在图片文件,否则删除该目录
517
+                        $isExistPic = $this->isExistPic("$directory/$dir");
518
+                        if (!empty($isExistPic)) {
519
+                            $arr_file[] = [
520
+                                'id'        => $num,
521
+                                'url'       => url('Uploadimgnew/get_dir_imglist',['num'=>$param['num'],'lang'=>$this->admin_lang,'images_path'=>"$directory/$dir"]),
522
+                                'target'    => 'content_body',
523
+                                'isParent'  => false,
524
+                                'open'      => false,
525
+                                'dirpath'   => "$directory/$dir",
526
+                                'level'     => $level,
527
+                                'icon'      => 'public/plugins/ztree/css/zTreeStyle/img/dir_close.png',
528
+                                'iconOpen'  => 'public/plugins/ztree/css/zTreeStyle/img/dir_open.png',
529
+                                'iconClose' => 'public/plugins/ztree/css/zTreeStyle/img/dir_close.png',
530
+                                'total'     => $total,
531
+                            ];
532
+                        }
533
+                    } else {
534
+                        @rmdir("$directory/$dir");
535
+                    }
536
+                }
537
+            }
538
+        }
539
+        return $arr_file;
540
+    }
541
+
542
+    /**
543
+     *  远程图片本地化
544
+     * @access    public
545
+     * @return    string
546
+     */
547
+    public function ajax_remote_to_imglocal()
548
+    {
549
+        if (IS_AJAX_POST) {
550
+            $post = input('post.');
551
+            $type_id = !empty($post['type_id']) ? $post['type_id'] : 0;
552
+            $imgremoteurl = !empty($post['imgremoteurl']) ? trim($post['imgremoteurl']) : '';
553
+            if (empty($imgremoteurl)) {
554
+                $this->error("请输入图片地址!");
555
+            } else if (!is_http_url($imgremoteurl)) {
556
+                $this->error("请输入有效的图片地址!");
557
+            }
558
+            $reData = saveRemote($imgremoteurl);
559
+            $reData = json_decode($reData, true);
560
+            if ('SUCCESS' != $reData['state']) {
561
+                $msg = !empty($reData['state']) ? $reData['state'] : '源网站图片可能已开启防盗链功能!';
562
+                $this->error($msg);
563
+            } else {
564
+                if (is_http_url($reData['url'])) {
565
+                    $image_url = $reData['url'];
566
+                } else {
567
+                    $image_url = handle_subdir_pic($reData['url']);
568
+                }
569
+            }
570
+
571
+            // 添加图片进数据库
572
+            $addData = [
573
+                'aid'         => 0,
574
+                'type_id'     => $type_id,
575
+                'image_url'   => $image_url,
576
+                'title'       => !empty($reData['title']) ? $reData['title'] : '',
577
+                'intro'       => '',
578
+                'width'       => $reData['width'],
579
+                'height'      => $reData['height'],
580
+                'filesize'    => $reData['size'],
581
+                'mime'        => $reData['mime'],
582
+                'users_id'    => (int)session('admin_info.syn_users_id'),
583
+                'sort_order'  => 100,
584
+                'add_time'    => getTime(),
585
+                'update_time' => getTime(),
586
+            ];
587
+            Db::name('uploads')->add($addData);
588
+            $this->success('提取成功', null, $addData);
589
+        }
590
+        $this->error('提取失败');
591
+    }
592
+
593
+    /*------------------------------------新版上传图片带分组 start-----------------------------------*/
594
+    //添加栏目
595
+    public function Addtype()
596
+    {
597
+        if (IS_AJAX_POST) {
598
+            $post = input('post.');
599
+            $upload_type = trim($post['upload_type']);
600
+            if (empty($upload_type)) $this->error("请输入分组名称");
601
+
602
+            $data = [
603
+                'upload_type' => $upload_type,
604
+                'add_time'    => getTime(),
605
+                'update_time' => getTime(),
606
+            ];
607
+            $rs = Db::name('UploadsType')->add($data);
608
+            if (!empty($rs)) {
609
+                $this->success("分组添加成功");
610
+            }
611
+        }
612
+        $this->error("分组添加失败");
613
+    }
614
+
615
+    // 编辑栏目
616
+    public function EditType()
617
+    {
618
+        if (IS_AJAX_POST) {
619
+            $post = input('post.');
620
+
621
+            $type_id = $post['type_id'];
622
+            if (empty($type_id)) $this->error("请选择分组");
623
+
624
+            $upload_type = trim($post['upload_type']);
625
+            if (empty($upload_type)) $this->error("请输入分组名称");
626
+
627
+            $data = [
628
+                'upload_type' => $upload_type,
629
+                'add_time'    => getTime(),
630
+                'update_time' => getTime(),
631
+            ];
632
+            $rs = Db::name('UploadsType')->where('id', $type_id)->update($data);
633
+            if (!empty($rs)) {
634
+                $this->success("分组编辑成功");
635
+            }
636
+        }
637
+        $this->error("分组编辑失败");
638
+    }
639
+
640
+    // 删除栏目
641
+    public function DelType()
642
+    {
643
+        if (IS_AJAX_POST) {
644
+            $post = input('post.');
645
+
646
+            $type_id = $post['type_id'];
647
+            if (empty($type_id)) $this->error("请选择分组");
648
+
649
+            $rs = Db::name('UploadsType')->where('id', $type_id)->delete();
650
+            if (!empty($rs)) {
651
+                Db::name('uploads')->where('type_id', $type_id)->update(['type_id' => 0, 'update_time'=>getTime()]);
652
+                $this->success("删除分组成功");
653
+            }
654
+        }
655
+        $this->error("分组添加失败");
656
+    }
657
+    
658
+    // 批量删除
659
+    public function del_uploadsimg() 
660
+    {
661
+        $img_id = input('img_id/a');
662
+        $img_id = eyIntval($img_id);
663
+        if (IS_POST && !empty($img_id)) {
664
+            $rs = Db::name('uploads')->where("img_id", 'IN', $img_id)->delete();
665
+            // $rs = Db::name('uploads')->where("img_id", 'IN', $img_id)->update(['is_del' => 1, 'update_time'=>getTime()]);
666
+            if ($rs !== false) {
667
+                $this->success("删除成功");
668
+            }
669
+        }
670
+        $this->error("删除失败");
671
+    }
672
+    /*------------------------------------新版上传图片带分组 end-----------------------------------*/
673
+
674
+
675
+    /*---------------------------------同步图片目录的图片到记录表 start 老许-------------------------*/
676
+    //更新旧数据弹出框
677
+    public function site(){
678
+        $admin_logic_1639031991 = tpSetting('syn.admin_logic_1639031991', [], 'cn');
679
+        if (!empty($admin_logic_1639031991)){
680
+            $this->error("已经同步过,不能重复同步");
681
+        }
682
+
683
+        return $this->fetch();
684
+    }
685
+
686
+    //分批次更新旧数据入口
687
+    public function build_site(){
688
+        $admin_logic_1639031991 = tpSetting('syn.admin_logic_1639031991', [], 'cn');
689
+        if (!empty($admin_logic_1639031991)){
690
+            $this->error("已经同步过,不能重复同步");
691
+        }
692
+        $achievepage = input("param.achieve/d", 0); // 已完成文档数
693
+        if (empty($findex) && empty($achievepage)){
694
+            $this->clearCache();
695
+        }
696
+
697
+        list($msg,$data) = $this->handel_build_site($achievepage,50);
698
+
699
+        $this->success($msg, null, $data);
700
+    }
701
+
702
+    //处理更新
703
+    private function handel_build_site($achievepage = 0,  $limit = 50){
704
+        $msg                  = "";
705
+        list($files,$pagetotal)  = $this->get_files_data();
706
+        $data['allpagetotal'] = $pagetotal;   //全部数据总数
707
+        if ($pagetotal > $achievepage){
708
+            $uploadsData = [];
709
+            while ($limit && isset($files[$achievepage])) {
710
+                $fileInfo = $files[$achievepage];
711
+                $url = !empty($fileInfo['url']) ? $fileInfo['url'] : '';
712
+                //获取文件其他信息(图片宽度、图片高度、文件大小、图片类型、图片上传时间)
713
+                $url = handle_subdir_pic($url, 'img', false, true);
714
+                $imageInfo = @getimagesize('.'.$url);
715
+                $mtime = $this->get_mtime($fileInfo['mtime'],$fileInfo['url']);
716
+                $uploadsData[] = [
717
+                    'image_url' => $fileInfo['url'],
718
+                    'filesize' => filesize('.'.$url),
719
+                    'width' => !empty($imageInfo[0]) ? $imageInfo[0] : 0,
720
+                    'height' => !empty($imageInfo[1]) ? $imageInfo[1] : 0,
721
+                    'mime' => !empty($imageInfo['mime']) ? $imageInfo['mime'] : 0,
722
+                    'add_time' => $mtime,
723
+                    'update_time' => $mtime
724
+                ];
725
+                $limit--;
726
+                $achievepage++;
727
+            }
728
+            if (!empty($uploadsData)){
729
+                Db::name("uploads")->insertAll($uploadsData);
730
+            }
731
+        }
732
+        $data['achievepage']  = $achievepage; //当前已完成总数(当前下标)
733
+        if ($data['allpagetotal'] == $data['achievepage']){   //生成全部页面,清楚缓存,增加标识
734
+            $this->clearCache();
735
+            $admin_logic_1639031991 = tpSetting('syn.admin_logic_1639031991', [], 'cn');
736
+            if (empty($admin_logic_1639031991)) {
737
+                tpSetting('syn', ['admin_logic_1639031991'=>1], 'cn');
738
+            }
739
+        }
740
+
741
+        return [$msg, $data];
742
+    }
743
+
744
+    /*
745
+     * 获取绝对的图片添加时间
746
+     * $mtime   文件添加时间
747
+     * $url     文件路径
748
+     */
749
+    private function get_mtime($mtime,$url){
750
+        if (!empty($mtime)){
751
+            return $mtime;
752
+        }
753
+        if (!empty($url)){
754
+            $dirArr = explode('/',$url);
755
+            $length = count($dirArr);
756
+            if ($length > 2){
757
+                $dir = $dirArr[$length - 2];
758
+                $mtime = strtotime($dir);
759
+                if (!empty($mtime)){
760
+                    return $mtime;
761
+                }
762
+            }
763
+        }
764
+
765
+        return time();
766
+    }
767
+
768
+    //获取缓存
769
+    private function get_files_data(){
770
+        $get_files_data_serialize = cache("get_files_data_serialize".$this->php_sessid);
771
+        if (empty($get_files_data_serialize)){
772
+            $allowFiles = str_replace(',', '|', $this->image_type);
773
+            $files = $this->getfiles(UPLOAD_PATH, $allowFiles, '');
774
+            $pagetotal = count($files);
775
+            cache("get_files_data_serialize".$this->php_sessid, serialize($files));
776
+            cache("get_files_total_serialize".$this->php_sessid, $pagetotal);
777
+
778
+        }else{
779
+            $files = unserialize($get_files_data_serialize);
780
+            $pagetotal        = cache("get_files_total_serialize".$this->php_sessid);
781
+        }
782
+        return [$files,$pagetotal];
783
+
784
+    }
785
+
786
+    //清楚缓存
787
+    private function clearCache(){
788
+        cache("get_fiels_data_serialize".$this->php_sessid, null);
789
+        cache("count_files_data_serialize".$this->php_sessid, null);
790
+    }
791
+    /*---------------------------------同步图片目录的图片到记录表 end 老许-------------------------*/
792
+}

+ 387
- 0
application/admin/controller/UsersNotice.php View File

@@ -0,0 +1,387 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class UsersNotice extends Base
21
+{
22
+    /**
23
+     * 构造方法
24
+     */
25
+    public function __construct(){
26
+        parent::__construct();
27
+
28
+        $this->language_access(); // 多语言功能操作权限
29
+        
30
+        // 会员中心配置信息
31
+        $this->UsersConfigData = getUsersConfigData('all');
32
+        $this->assign('userConfig',$this->UsersConfigData);
33
+    }
34
+
35
+    /**
36
+     * 站内通知 - 列表
37
+     */
38
+    public function index()
39
+    {
40
+        $list = array();
41
+        $keywords = input('keywords/s');
42
+
43
+        $map = array();
44
+        if (!empty($keywords)) {
45
+            $map['title'] = array('LIKE', "%{$keywords}%");
46
+        }
47
+
48
+        $count = Db::name('users_notice')->where($map)->count('id');// 查询满足要求的总记录数
49
+        $pageObj = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
50
+        $list = Db::name('users_notice')->where($map)->order('id desc')->limit($pageObj->firstRow.','.$pageObj->listRows)->select();
51
+        if ($list) {
52
+            foreach ($list as $k=>$v) {
53
+                $usernames_str = '';
54
+                if ($v['users_id']) {
55
+                    $usernames_arr = explode(',', $v['users_id']);
56
+                    if (count($usernames_arr) > 3) {
57
+                        for ($i = 0; $i < 3; $i++) {
58
+                            $usernames_str .= $usernames_arr[$i] . ',';
59
+                        }
60
+                        $usernames_str .= ' ...';
61
+                        $list[$k]['usernames'] = $usernames_str;
62
+                    }else{
63
+                        $list[$k]['usernames'] =  $v['users_id'];
64
+                    }
65
+                }else{
66
+                    $list[$k]['usernames'] = '全站会员';
67
+                }
68
+            }
69
+        }
70
+
71
+        $pageStr = $pageObj->show(); // 分页显示输出
72
+        $this->assign('list', $list); // 赋值数据集
73
+        $this->assign('page', $pageStr); // 赋值分页输出
74
+        $this->assign('pager', $pageObj); // 赋值分页对象
75
+
76
+        return $this->fetch();
77
+    }
78
+
79
+    /**
80
+     * 站内通知 - 新增
81
+     */
82
+    public function add()
83
+    {
84
+        $web_is_authortoken = tpCache('global.web_is_authortoken');
85
+        if (-1 == $web_is_authortoken) {
86
+            $this->error('该功能仅限于商业授权域名!');
87
+        }
88
+        
89
+        if (IS_POST) {
90
+            $post = input('post.');
91
+
92
+            /*组装存储数据*/
93
+            $nowData = array(
94
+                'add_time'    => getTime(),
95
+                'update_time'    => getTime(),
96
+            );
97
+            empty($post['usernames']) && $post['usernames'] = "";
98
+            $saveData = array_merge($post, $nowData);
99
+            /*--end*/
100
+            $insertId = Db::name('users_notice')->insertGetId($saveData);
101
+
102
+            if ($insertId) {
103
+                //未读消息数+1
104
+                if (!empty($post['users_id'])){
105
+                    Db::name('users')->where(['users_id' => ['IN', $post['users_id']]])->setInc('unread_notice_num');
106
+                }else{
107
+                    Db::name('users')->where(['users_id' => ['gt', 0]])->setInc('unread_notice_num');
108
+                }
109
+                
110
+                if (!empty($post['users_id'])){
111
+                    adminLog('新增站内通知:通知会员id为:'.$post['users_id'].' ,新增站内通知:通知会员名为:'.$post['usernames']); // 写入操作日志
112
+                }else{
113
+                    adminLog('新增全站通知'); // 写入操作日志
114
+                }
115
+                $this->success("操作成功", url('UsersNotice/index'));
116
+            }else{
117
+                $this->error("操作失败");
118
+            }
119
+            exit;
120
+        }
121
+
122
+        $listname = Db::name('users')->order('users_id desc')->field('users_id,username')->select();
123
+        $this->assign('listname', $listname);
124
+        return $this->fetch();
125
+    }
126
+
127
+    /**
128
+     * 站内通知 - 编辑
129
+     */
130
+    public function edit()
131
+    {
132
+        if (IS_POST) {
133
+            $post = input('post.');
134
+            $post['id'] = intval($post['id']);
135
+            if (isset($post['usernames'])) unset($post['usernames']);
136
+            if (isset($post['users_id'])) unset($post['users_id']);
137
+
138
+            $post['id'] = eyIntval($post['id']);
139
+            if(!empty($post['id'])){
140
+                $post['update_time'] = getTime();
141
+                $r = Db::name('users_notice')->where(['id'=>$post['id']])->update($post);
142
+                if ($r) {
143
+                    adminLog('编辑站内通知:通知id为'.$post['id']); // 写入操作日志
144
+                    $this->success("操作成功!", url('UsersNotice/index'));
145
+                }
146
+            }
147
+            $this->error("操作失败!");
148
+        }
149
+
150
+        $id = input('id/d', 0);
151
+        $row = Db::name('users_notice')->find($id);
152
+        if (empty($row)) {
153
+            $this->error('数据不存在,请联系管理员!');
154
+            exit;
155
+        }
156
+
157
+        // 转化换行格式,适应输出
158
+        $row['remark'] = str_replace("<br/>", "\n", $row['remark']);
159
+
160
+        $listname = Db::name('users')->order('users_id desc')->field('users_id,username')->select();
161
+        $this->assign('listname', $listname);
162
+
163
+        $this->assign('row',$row);
164
+        return $this->fetch();
165
+    }
166
+
167
+    /**
168
+     * 站内通知 - 删除
169
+     */
170
+    public function del()
171
+    {
172
+        $id_arr = input('del_id/a');
173
+        $id_arr = eyIntval($id_arr);
174
+        if(!empty($id_arr) && IS_POST){
175
+            $result = Db::name('users_notice')->where("id",'IN',$id_arr)->select();
176
+            $r = Db::name('users_notice')->where("id",'IN',$id_arr)->delete();
177
+            if($r !== false){
178
+                $usersTplVersion = getUsersTplVersion();
179
+                if ($usersTplVersion != 'v1') {
180
+                    //未读消息数-1
181
+                    foreach ($result as $item) {
182
+                        if ($item['users_id']) {
183
+                            $users_id_arr_new = explode(",", $item['users_id']);
184
+                            Db::name('users')->where(['users_id' => ['IN', $users_id_arr_new], 'unread_notice_num'=>['gt', 0]])->setDec('unread_notice_num');
185
+                        }else{
186
+                            //通知的是全站会员
187
+                            Db::name('users')->where(['unread_notice_num'=>['gt', 0]])->setDec('unread_notice_num');
188
+                        }
189
+                    }
190
+                }
191
+                Db::name('users_notice_read')->where("notice_id",'IN',$id_arr)->delete();
192
+                adminLog('删除站内通知:'.implode(',', $id_arr));
193
+                $this->success("删除成功!");
194
+            }
195
+        }
196
+        $this->error("删除失败!");
197
+    }
198
+
199
+    /**
200
+     * 站内通知 - 管理员接收通知列表
201
+     */
202
+    public function admin_notice_index()
203
+    {
204
+        $list = array();
205
+        $keywords = input('keywords/s');
206
+
207
+        $map = array();
208
+        if (!empty($keywords)) {
209
+            $map['a.content_title'] = array('LIKE', "%{$keywords}%");
210
+        }
211
+
212
+        $count = Db::name('users_notice_tpl_content')->alias('a')->where($map)->count('content_id');
213
+        $pageObj = new Page($count, config('paginate.list_rows'));
214
+        $list = Db::name('users_notice_tpl_content')
215
+            ->field('a.*, b.tpl_name')
216
+            ->alias('a')
217
+            ->join('__USERS_NOTICE_TPL__ b', 'a.source = b.send_scene', 'LEFT')
218
+            ->where($map)
219
+            ->order('content_id desc')
220
+            ->limit($pageObj->firstRow.','.$pageObj->listRows)
221
+            ->select();
222
+
223
+        $pageStr = $pageObj->show(); // 分页显示输出
224
+        $this->assign('list', $list); // 赋值数据集
225
+        $this->assign('page', $pageStr); // 赋值分页输出
226
+        $this->assign('pager', $pageObj); // 赋值分页对象
227
+
228
+        return $this->fetch();
229
+    }
230
+
231
+    /**
232
+     * 站内通知 - 编辑管理员接收通知
233
+     */
234
+    public function admin_notice_edit()
235
+    {
236
+        $content_id = input('content_id/d', 0);
237
+        $Find = Db::name('users_notice_tpl_content')->field('a.*, b.tpl_name')->alias('a')->join('__USERS_NOTICE_TPL__ b', 'a.source = b.send_scene', 'LEFT')->find($content_id);
238
+        if (empty($Find)) $this->error('数据不存在,请联系管理员!');
239
+
240
+        // 更新通知为已查看
241
+        if (empty($Find['is_read'])) {
242
+            $update = [
243
+                'content_id'  => $Find['content_id'],
244
+                'is_read'     => 1,
245
+                'update_time' => getTime()
246
+            ];
247
+            Db::name('users_notice_tpl_content')->update($update);
248
+        }
249
+
250
+        $this->assign('find', $Find);
251
+        return $this->fetch();
252
+    }
253
+
254
+    /**
255
+     * 站内通知 - 删除管理员接收通知
256
+     */
257
+    public function admin_notice_del()
258
+    {
259
+        $id_arr = input('del_id/a');
260
+        $id_arr = eyIntval($id_arr);
261
+        if(!empty($id_arr) && IS_POST) {
262
+            // 查询要删除的通知信息
263
+            $result = Db::name('users_notice_tpl_content')->field('content_id')->where("content_id", 'IN', $id_arr)->select();
264
+            // 获取ID列表
265
+            $id_list = get_arr_column($result, 'content_id');
266
+            // 执行删除
267
+            $DeleteID = Db::name('users_notice_tpl_content')->where("content_id", 'IN', $id_arr)->delete();
268
+            // 添加操作日志,返回结束
269
+            if (!empty($DeleteID)) {
270
+                adminLog('删除接收的站内通知:' . implode(',', $id_list));
271
+                $this->success("删除成功");
272
+            } else {
273
+                $this->error("删除失败");
274
+            }
275
+        } else {
276
+            $this->error("参数有误");
277
+        }
278
+    }
279
+
280
+    /**
281
+     * 全部标记已读
282
+     */
283
+    public function sign_admin_allread()
284
+    {
285
+        if (IS_AJAX_POST) {
286
+            $update = [
287
+                'is_read'     => 1,
288
+                'update_time' => getTime()
289
+            ];
290
+            $r = Db::name('users_notice_tpl_content')->where(['admin_id'=>['gt', 0]])->update($update);
291
+            if ($r !== false) {
292
+                $this->success('操作成功');
293
+            }
294
+        }
295
+        $this->error('操作失败');
296
+    }
297
+
298
+    public function select_users()
299
+    {
300
+        $list = array();
301
+
302
+        $param = input('param.');
303
+        $condition = array();
304
+        // 应用搜索条件
305
+        foreach (['keywords','origin_type','level'] as $key) {
306
+            if (isset($param[$key]) && $param[$key] !== '') {
307
+                if ($key == 'keywords') {
308
+                    $condition['a.username|a.nickname|a.mobile|a.email|a.users_id'] = array('LIKE', "%{$param[$key]}%");
309
+                } else {
310
+                    $condition['a.'.$key] = array('eq', $param[$key]);
311
+                }
312
+            }
313
+        }
314
+
315
+        $condition['a.is_del'] = 0;
316
+        $condition['a.lang'] = array('eq', $this->admin_lang);
317
+        $orderby = "a.users_id desc";
318
+
319
+        $users_db = Db::name('users');
320
+
321
+        $count = $users_db->alias('a')->where($condition)->count();
322
+        $Page = new Page($count, config('paginate.list_rows'));
323
+        $list = $users_db->field('a.*,b.level_name')
324
+            ->alias('a')
325
+            ->join('__USERS_LEVEL__ b', 'a.level = b.level_id', 'LEFT')
326
+            ->where($condition)
327
+            ->order($orderby)
328
+            ->limit($Page->firstRow.','.$Page->listRows)
329
+            ->select();
330
+        $users_ids = [];
331
+        foreach ($list as $key => $val) {
332
+            $users_ids[] = $val['users_id'];
333
+        }
334
+
335
+        /*微信登录插件*/
336
+        $wxlogin = [];
337
+        if (is_dir('./weapp/WxLogin/')) {
338
+            $wxlogin = Db::name('weapp_wxlogin')->where(['users_id'=>['IN', $users_ids]])->getAllWithIndex('users_id');
339
+        }
340
+        $this->assign('wxlogin',$wxlogin);
341
+        /*end*/
342
+
343
+        /*QQ登录插件*/
344
+        $qqlogin = [];
345
+        if (is_dir('./weapp/QqLogin/')) {
346
+            $qqlogin = Db::name('weapp_qqlogin')->where(['users_id'=>['IN', $users_ids]])->getAllWithIndex('users_id');
347
+        }
348
+        $this->assign('qqlogin',$qqlogin);
349
+        /*end*/
350
+
351
+        /*微博登录插件*/
352
+        $wblogin = [];
353
+        if (is_dir('./weapp/Wblogin/')) {
354
+            $wblogin = Db::name('weapp_wblogin')->where(['users_id'=>['IN', $users_ids]])->getAllWithIndex('users_id');
355
+        }
356
+        $this->assign('wblogin',$wblogin);
357
+        /*end*/
358
+
359
+        $show = $Page->show();
360
+        $this->assign('page',$show);
361
+        $this->assign('list',$list);
362
+        $this->assign('pager',$Page);
363
+
364
+        //计算会员人数
365
+        $levelCountList = [
366
+            'all' => [
367
+                'level_id'      => 0,
368
+                'level_name'    => '全部会员',
369
+                'level_count'   => 0,
370
+            ],
371
+        ];
372
+        $LevelData = model('UsersLevel')->getList('level_id, level_name', [], 'level_id');
373
+        $levelCountRow = Db::name('users')->field('count(users_id) as num, level')->order('level asc')->group('level')->getAllWithIndex('level');
374
+        foreach ($LevelData as $key => $val) {
375
+            $level_num = empty($levelCountRow[$val['level_id']]) ? 0 : $levelCountRow[$val['level_id']]['num'];
376
+            $levelCountList[$val['level_id']] = [
377
+                'level_id'      => $val['level_id'],
378
+                'level_name'    => $val['level_name'],
379
+                'level_count'   => $level_num,
380
+            ];
381
+            $levelCountList['all']['level_count'] += $level_num;
382
+        }
383
+        $this->assign('levelCountList', $levelCountList);
384
+
385
+        return $this->fetch('users_notice/select_users');
386
+    }
387
+}

+ 114
- 0
application/admin/controller/UsersRelease.php View File

@@ -0,0 +1,114 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 陈风任 <491085389@qq.com>
11
+ * Date: 2019-07-04
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Config;
18
+
19
+class UsersRelease extends Base {
20
+
21
+    public $current_channel = [1,3,4,5];
22
+    public function __construct(){
23
+        parent::__construct();
24
+
25
+        // 会员中心配置信息
26
+        $this->UsersConfigData = getUsersConfigData('all');
27
+        $this->assign('userConfig',$this->UsersConfigData);
28
+
29
+        // 模型是否开启
30
+        $channeltype_row = \think\Cache::get('extra_global_channeltype');
31
+        $this->assign('channeltype_row',$channeltype_row);
32
+//        $this->current_channel = Db::name('channeltype')->where('is_release',1)->where('id','in',$this->current_channel)->column('id');
33
+    }
34
+
35
+    /**
36
+     * 商城设置
37
+     */
38
+    public function conf(){
39
+        if (IS_AJAX) {
40
+            $is_automatic_review = input('param.is_automatic_review/d', 0);
41
+            $is_open_posts_count = input('param.is_open_posts_count/d', 0);
42
+            $release_typeids = input('param.release_typeids/s', '');
43
+            $typeids = !empty($release_typeids) ? explode(',', $release_typeids) : [];
44
+
45
+            $confData = [
46
+                'is_automatic_review' => $is_automatic_review,
47
+                'is_open_posts_count' => $is_open_posts_count,
48
+                'release_default_id' => !empty($typeids[0]) ? intval($typeids[0]) : 0,
49
+            ];
50
+            getUsersConfigData('users', $confData);
51
+
52
+            /*设置可投稿的栏目*/
53
+            // $typeids = explode(',', $release_typeids);
54
+            $where = [
55
+                'id' => ['IN', $typeids],
56
+            ];
57
+            if (0 == $typeids[0]) {
58
+                $where = [
59
+                    'current_channel' => ['in',$this->current_channel],
60
+                    'lang' => $this->admin_lang,
61
+                ];
62
+            }
63
+            $update = [
64
+                'is_release' => 1,
65
+                'update_time' => getTime(),
66
+            ];
67
+            if (!empty($where) && !empty($update)) {
68
+                /*将全部设置为不可投稿*/
69
+                Db::name('arctype')->where([
70
+                    'current_channel' => ['in',$this->current_channel],
71
+                    'lang' => $this->admin_lang,
72
+                ])->update([
73
+                    'is_release' => 0,
74
+                    'update_time' => getTime(),
75
+                ]);
76
+                /* END */
77
+
78
+                /*设置选择的栏目为可投稿*/
79
+                Db::name('arctype')->where($where)->update($update);
80
+                /* END */
81
+            }
82
+            /* END */
83
+            
84
+            $this->success('设置成功!');
85
+        }
86
+        // 会员投稿配置信息
87
+        $UsersC = getUsersConfigData('users');
88
+        $this->assign('UsersC',$UsersC);
89
+        /*允许发布文档列表的栏目*/
90
+        $arctype = Db::name('arctype')->where([
91
+            'current_channel' => ['in',$this->current_channel],
92
+            'is_release' => 1,
93
+            'lang' => $this->admin_lang,
94
+        ])->field('id')->select();
95
+        $arctype = get_arr_column($arctype,'id');
96
+        $select_html = allow_release_arctype($arctype, $this->current_channel);
97
+        if (empty($this->current_channel)){
98
+            $select_html = [];
99
+        }
100
+        $this->assign('select_html',$select_html);
101
+        /*--end*/
102
+        return $this->fetch('conf');
103
+    }
104
+
105
+    public function ajax_users_level_bout()
106
+    {
107
+        $UsersLevel = model('UsersLevel')->getList();
108
+        $LevelCount = count($UsersLevel);
109
+
110
+        $this->assign('list',$UsersLevel);
111
+        $this->assign('LevelCount',$LevelCount);
112
+        return $this->fetch();   
113
+    }
114
+}

+ 98
- 0
application/admin/controller/UsersScore.php View File

@@ -0,0 +1,98 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Db;
17
+use think\Page;
18
+use think\Cache;
19
+
20
+class UsersScore extends Base
21
+{
22
+    /**
23
+     * 构造方法
24
+     */
25
+    public function __construct(){
26
+        parent::__construct();
27
+
28
+        $functionLogic = new \app\common\logic\FunctionLogic;
29
+        $functionLogic->validate_authorfile(1.5);
30
+
31
+        $this->language_access(); // 多语言功能操作权限
32
+
33
+        // 会员中心配置信息
34
+        $this->UsersConfigData = getUsersConfigData('all');
35
+        $this->assign('userConfig',$this->UsersConfigData);
36
+    }
37
+
38
+    public function index()
39
+    {
40
+        $list     = array();
41
+        $keywords = input('keywords/s');
42
+
43
+        $condition = [
44
+            'type' => ['IN', [1, 2, 5, 8, 10]], // 1(提问)、2(回答)、5(签到)、8(消费赠送)、10(登录赠送积分)
45
+        ];
46
+        //时间检索条件
47
+        $begin    = strtotime(input('param.add_time_begin/s'));
48
+        $end    = input('param.add_time_end/s');
49
+        !empty($end) && $end .= ' 23:59:59';
50
+        $end    = strtotime($end);
51
+        // 时间检索
52
+        if ($begin > 0 && $end > 0) {
53
+            $condition['a.add_time'] = array('between',"$begin,$end");
54
+        } else if ($begin > 0) {
55
+            $condition['a.add_time'] = array('egt', $begin);
56
+        } else if ($end > 0) {
57
+            $condition['a.add_time'] = array('elt', $end);
58
+        }
59
+
60
+        if ($keywords)  $condition['b.username'] = array('LIKE', "%{$keywords}%");
61
+
62
+        $condition['a.lang'] = $this->admin_lang;
63
+
64
+        $count  = Db::name('users_score')->alias('a')->join('users b','a.users_id = b.users_id')->where($condition)->count('id');// 查询满足要求的总记录数
65
+        $Page   = $pager = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
66
+        $list   = Db::name('users_score')
67
+            ->alias('a')
68
+            ->field('a.*,b.username,b.head_pic,b.nickname')
69
+            ->join('users b','a.users_id = b.users_id')
70
+            ->where($condition)
71
+            ->order('id desc')
72
+            ->limit($Page->firstRow . ',' . $Page->listRows)
73
+            ->select();
74
+
75
+        $show = $Page->show();// 分页显示输出
76
+        $this->assign('page', $show);// 赋值分页输出
77
+        $this->assign('list', $list);// 赋值数据集
78
+        $this->assign('pager', $pager);// 赋值分页对象
79
+        return $this->fetch();
80
+    }
81
+
82
+    /**
83
+     * 积分设置
84
+     */
85
+    public function conf()
86
+    {
87
+        if (IS_POST) {
88
+            $post     = input('post.');
89
+            $functionLogic = new \app\common\logic\FunctionLogic;
90
+            $functionLogic->scoreConf($post);
91
+            $this->success("操作成功", url('UsersScore/conf'));
92
+        }
93
+        $score = getUsersConfigData('score');
94
+        $this->assign('score', $score);
95
+
96
+        return $this->fetch();
97
+    }
98
+}

+ 85
- 0
application/admin/controller/Vertify.php View File

@@ -0,0 +1,85 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\controller;
15
+
16
+use think\Config;
17
+
18
+class Vertify extends Base
19
+{
20
+
21
+    public function _initialize() {
22
+        parent::_initialize();
23
+    }
24
+
25
+    /**
26
+     * 验证码管理
27
+     */
28
+    public function index()
29
+    {
30
+        // 获取插件数据
31
+        $row = tpSetting('system.system_vertify');
32
+        if (IS_POST) {
33
+            // 获取post参数
34
+            $inc_type = input('inc_type/s', 'admin_login');
35
+            $param = $this->request->only('captcha');
36
+            $config = json_decode($row, true);
37
+
38
+            if ('default' == $inc_type) {
39
+                if (isset($config[$inc_type])) {
40
+                    $config['captcha'][$inc_type] = array_merge($config['captcha'][$inc_type], $param['captcha'][$inc_type]);
41
+                } else {
42
+                    $config['captcha'][$inc_type] = $param['captcha'][$inc_type];
43
+                }
44
+            } else {
45
+                $config['captcha'][$inc_type]['is_on'] = $param['captcha'][$inc_type]['is_on'];
46
+                if (isset($config['captcha'][$inc_type]['config'])) {
47
+                    $config['captcha'][$inc_type]['config'] = array_merge($config['captcha'][$inc_type]['config'], $param['captcha'][$inc_type]['config']);
48
+                } else {
49
+                    $config['captcha'][$inc_type]['config'] = $param['captcha'][$inc_type]['config'];
50
+                }
51
+            }
52
+            // 转json赋值
53
+            $row = json_encode($config);
54
+            $r = tpSetting('system',['system_vertify'=>$row]);
55
+
56
+            if ($r !== false) {
57
+                adminLog('编辑验证码配置'); // 写入操作日志
58
+                $this->success("操作成功!", url('Vertify/index', ['inc_type'=>$inc_type]));
59
+            }
60
+            $this->error("操作失败!");
61
+        }
62
+
63
+        $inc_type = input('param.inc_type/s', 'admin_login');
64
+        $inc_type = preg_replace('/([^\w\-]+)/i', '', $inc_type);
65
+
66
+        // 获取配置JSON信息转数组
67
+        $config = json_decode($row, true);
68
+        $baseConfig = Config::get("captcha");
69
+
70
+        if ('default' == $inc_type) {
71
+            $row = isset($config['captcha']) ? $config['captcha'] : $baseConfig;
72
+        } else {
73
+            if (isset($config['captcha'][$inc_type])) {
74
+                $row = $config['captcha'][$inc_type];
75
+            } else {
76
+                $baseConfig[$inc_type]['config'] = !empty($config['captcha']['default']) ? $config['captcha']['default'] : $baseConfig['default'];
77
+                $row = $baseConfig[$inc_type];
78
+            }
79
+        }
80
+
81
+        $this->assign('row', $row);
82
+        $this->assign('inc_type', $inc_type);
83
+        return $this->fetch($inc_type);
84
+    }
85
+}

+ 10
- 0
application/admin/controller/Weapp.php
File diff suppressed because it is too large
View File


+ 24
- 0
application/admin/html.php View File

@@ -0,0 +1,24 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+return array(
15
+    // 模板设置
16
+    'template' => array(
17
+        // 模板路径
18
+        'view_path' => './application/admin/template/',
19
+        // 模板后缀
20
+        'view_suffix' => 'htm',
21
+    ),
22
+    'view_replace_str' => array(),
23
+);
24
+?>

+ 4
- 0
application/admin/lang/en-us.php View File

@@ -0,0 +1,4 @@
1
+<?php
2
+return array(
3
+    
4
+);

+ 4
- 0
application/admin/lang/zh-cn.php View File

@@ -0,0 +1,4 @@
1
+<?php
2
+return array(
3
+    
4
+);

+ 1654
- 0
application/admin/logic/AjaxLogic.php
File diff suppressed because it is too large
View File


+ 741
- 0
application/admin/logic/ArchivesLogic.php View File

@@ -0,0 +1,741 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Model;
17
+use think\Db;
18
+
19
+/**
20
+ * 文档逻辑定义
21
+ * Class CatsLogic
22
+ * @package admin\Logic
23
+ */
24
+load_trait('controller/Jump');
25
+class ArchivesLogic extends Model
26
+{
27
+    use \traits\controller\Jump;
28
+    
29
+    private $admin_lang = 'cn';
30
+
31
+    /**
32
+     * 析构函数
33
+     */
34
+    function  __construct() {
35
+        $this->admin_lang = get_admin_lang();
36
+    }
37
+
38
+    /**
39
+     * 删除文档
40
+     */
41
+    public function del($del_id = array(), $thorough = 0, $table = '')
42
+    {
43
+        $del_id = !empty($del_id) ? $del_id : input('del_id/a');
44
+        $id_arr = eyIntval($del_id);
45
+        $_POST['aids'] = $id_arr;
46
+        $thorough = !empty($thorough) ? $thorough : input('thorough/d');
47
+        if (!empty($id_arr)) {
48
+            /*分离并组合相同模型下的文档ID*/
49
+            $field = 'a.aid, a.typeid, a.channel, a.arcrank, a.is_recom, a.is_special, a.is_b, a.is_head, a.is_litpic, a.is_jump, a.is_slide, a.is_roll, a.is_diyattr, a.users_id, b.table, b.ctl_name, b.ifsystem';
50
+            $row = Db::name('archives')
51
+                ->alias('a')
52
+                ->field($field)
53
+                ->join('__CHANNELTYPE__ b', 'a.channel = b.id', 'LEFT')
54
+                ->where([
55
+                    'a.aid' => ['IN', $id_arr],
56
+                    'a.lang'    => $this->admin_lang,
57
+                ])
58
+                ->select();
59
+
60
+            $data = array();
61
+            foreach ($row as $key => $val) {
62
+                $data[$val['channel']]['aid'][] = $val['aid'];
63
+                $data[$val['channel']]['table'] = $val['table'];
64
+                if (empty($val['ifsystem'])) {
65
+                    $ctl_name = 'Custom';
66
+                } else {
67
+                    $ctl_name = $val['ctl_name'];
68
+                }
69
+                $data[$val['channel']]['ctl_name'] = $ctl_name;
70
+            }
71
+            /*--end*/
72
+
73
+            // 删除静态文件
74
+            $buildhtmlLogic = new \app\common\logic\BuildhtmlLogic;
75
+            $buildhtmlLogic->delViewHtml($id_arr);
76
+
77
+            if (1 == $thorough) { // 直接删除,跳过回收站
78
+                $err = 0;
79
+                foreach ($data as $key => $val) {
80
+                    $r = Db::name('archives')->where('aid','IN',$val['aid'])->delete();
81
+                    if ($r) {
82
+                        if (empty($val['ifsystem'])) {
83
+                            model($val['ctl_name'])->afterDel($val['aid'], $val['table']);
84
+                        } else {
85
+                            model($val['ctl_name'])->afterDel($val['aid']);
86
+                        }
87
+                        adminLog('删除文档-id:'.implode(',', $val['aid']));
88
+                    } else {
89
+                        $err++;
90
+                    }
91
+                }
92
+            } else {
93
+                $info['is_del']     = 1; // 伪删除状态
94
+                $info['update_time']= getTime(); // 更新修改时间
95
+                $info['del_method'] = 1; // 恢复删除方式为默认
96
+
97
+
98
+                $numinfo = [
99
+                    'is_del' => 1,
100
+                ];
101
+
102
+                $err = 0;
103
+                foreach ($data as $key => $val) {
104
+                    $r = Db::name('archives')->where('aid','IN',$val['aid'])->update($info);
105
+                    if ($r) {
106
+                        adminLog('删除文档-id:'.implode(',', $val['aid']));
107
+                    } else {
108
+                        $err++;
109
+                    }
110
+
111
+                    //文档aid 对应 序列号aid
112
+                    Db::name('seo_number')->where('aid','IN',$val['aid'])->update($numinfo);
113
+
114
+                }
115
+            }
116
+
117
+            if (0 == $err) {
118
+                // 处理mysql缓存表数据
119
+                $DraftData = [
120
+                    'TypeID' => [],
121
+                    'UsersID' => [],
122
+                ];
123
+                foreach ($row as $key => $value) {
124
+                    if (-1 === $value['arcrank'] && !empty($value['users_id'])) {
125
+                        array_push($DraftData['TypeID'], $value['typeid']);
126
+                        array_push($DraftData['UsersID'], $value['users_id']);
127
+                        unset($row[$key]);
128
+                    }
129
+                }
130
+                if (!empty($row)) model('SqlCacheTable')->UpdateSqlCacheTable($row, 'del', $table);
131
+                if (!empty($DraftData)) model('SqlCacheTable')->UpdateDraftSqlCacheTable($DraftData, 'admin_del');
132
+
133
+                // 系统商品操作时,积分商品的被动处理
134
+                model('ShopPublicHandle')->pointsGoodsPassiveHandle($id_arr);
135
+
136
+                $this->success('删除成功!');
137
+            } else if ($err < count($data)) {
138
+                // 系统商品操作时,积分商品的被动处理
139
+                model('ShopPublicHandle')->pointsGoodsPassiveHandle($id_arr);
140
+
141
+                $this->success('删除部分成功!');
142
+            } else {
143
+                $this->error('删除失败!');
144
+            }
145
+        }else{
146
+            $this->error('文档不存在!');
147
+        }
148
+    }
149
+
150
+    /**
151
+     * 获取文档模板文件列表
152
+     */
153
+    public function getTemplateList($nid = 'article')
154
+    {   
155
+        $planPath = 'template/'.TPL_THEME.'pc';
156
+        $dirRes   = opendir($planPath);
157
+        $view_suffix = config('template.view_suffix');
158
+
159
+        /*模板PC目录文件列表*/
160
+        $templateArr = array();
161
+        while($filename = readdir($dirRes))
162
+        {
163
+            if (in_array($filename, array('.','..'))) {
164
+                continue;
165
+            }
166
+            array_push($templateArr, $filename);
167
+        }
168
+        /*--end*/
169
+
170
+        /*多语言全部标识*/
171
+        $markArr = Db::name('language_mark')->column('mark');
172
+        /*--end*/
173
+
174
+        $templateList = array();
175
+        foreach ($templateArr as $k2 => $v2) {
176
+            $v2 = iconv('GB2312', 'UTF-8', $v2);
177
+            preg_match('/^(view)_'.$nid.'(_(.*))?(_'.$this->admin_lang.')?\.'.$view_suffix.'/i', $v2, $matches1);
178
+            $langtpl = preg_replace('/\.'.$view_suffix.'$/i', "_{$this->admin_lang}.{$view_suffix}", $v2);
179
+            if (file_exists(realpath($planPath.DS.$langtpl))) {
180
+                continue;
181
+            } else if (preg_match('/^(.*)_([a-zA-z]{2,2})\.'.$view_suffix.'$/i',$v2,$matches2)) {
182
+                if (in_array($matches2[2], $markArr) && $matches2[2] != $this->admin_lang) {
183
+                    continue;
184
+                }
185
+            }
186
+
187
+            if (!empty($matches1)) {
188
+                if ('view' == $matches1[1]) {
189
+                    array_push($templateList, $v2);
190
+                }
191
+            }
192
+        }
193
+
194
+        return $templateList;
195
+    }
196
+
197
+    /**
198
+     * 复制文档
199
+     */
200
+    public function batch_copy($aids = [], $typeid = 0, $channel = 0, $num = 1)
201
+    {
202
+        // 获取复制栏目的模型ID
203
+        $channeltypeRow = Db::name('channeltype')->field('nid,table')
204
+            ->where([
205
+                'id'    => $channel,
206
+            ])->find();
207
+        if (!empty($channeltypeRow)) {
208
+            // 主表数据
209
+            $archivesRow = Db::name('archives')->where(['aid'=>['IN', $aids]])->select();
210
+            // 内容扩展表数据
211
+            $tableExt = $channeltypeRow['table']."_content";
212
+            $contentRow = Db::name($tableExt)->field('id', true)->where(['aid'=>['IN', $aids]])->getAllWithIndex('aid');
213
+
214
+            // 拥有特性模型的其他数据处理
215
+            if ('images' == $channeltypeRow['nid']) { // 图集模型的特性表数据
216
+                $imgUploadRow = Db::name('images_upload')->field('img_id', true)->where(['aid'=>['IN', $aids]])->select();
217
+                $imgUploadRow = group_same_key($imgUploadRow, 'aid');
218
+            } 
219
+            else if ('download' == $channeltypeRow['nid']) { // 下载模型的特性表数据
220
+                // 附件表
221
+                $downloadFileRow = Db::name('download_file')->field('file_id', true)->where(['aid'=>['IN', $aids]])->select();
222
+                $downloadFileRow = group_same_key($downloadFileRow, 'aid');
223
+            }
224
+            else if ('product' == $channeltypeRow['nid']) { // 产品模型的特性表数据
225
+                // 属性值表
226
+                $productAttrRow = Db::name('product_attr')->field('product_attr_id', true)->where(['aid'=>['IN', $aids]])->select();
227
+                $productAttrRow = group_same_key($productAttrRow, 'aid');
228
+                // 产品图集表
229
+                $productImgRow = Db::name('product_img')->field('img_id', true)->where(['aid'=>['IN', $aids]])->select();
230
+                $productImgRow = group_same_key($productImgRow, 'aid');
231
+                // 产品虚拟表
232
+                $productNetdiskRow = Db::name('product_netdisk')->field('nd_id', true)->where(['aid'=>['IN', $aids]])->select();
233
+                $productNetdiskRow = group_same_key($productNetdiskRow, 'aid');
234
+                // 产品规格数据表
235
+                $productSpecRow = Db::name('product_spec_data')->field('spec_id', true)->where(['aid'=>['IN', $aids]])->select();
236
+                $productSpecRow = group_same_key($productSpecRow, 'aid');
237
+                // 产品多规格组装表
238
+                $productSpecValueRow = Db::name('product_spec_value')->field('value_id', true)->where(['aid'=>['IN', $aids]])->select();
239
+                $productSpecValueRow = group_same_key($productSpecValueRow, 'aid');
240
+            }
241
+            else if ('media' == $channeltypeRow['nid']) { // 视频模型的特性表数据
242
+                // 附件表
243
+                $mediaFileRow = Db::name('media_file')->field('file_id', true)->where(['aid'=>['IN', $aids]])->select();
244
+                $mediaFileRow = group_same_key($mediaFileRow, 'aid');
245
+            }
246
+            else if ('special' == $channeltypeRow['nid']) { // 专题模型的特性表数据
247
+                // 节点表
248
+                $specialNodeRow = Db::name('special_node')->field('node_id', true)->where(['aid'=>['IN', $aids]])->select();
249
+                $specialNodeRow = group_same_key($specialNodeRow, 'aid');
250
+            }
251
+
252
+            foreach ($archivesRow as $key => $val) {
253
+                // 原先数据的栏目ID
254
+                $typeid_old = $val['typeid'];
255
+
256
+                // 同步数据
257
+                $archivesData = [];
258
+                for ($i = 0; $i < $num; $i++) {
259
+                    // 主表
260
+                    $archivesInfo = $val;
261
+                    unset($archivesInfo['aid']);
262
+                    $archivesInfo['typeid'] = $typeid;
263
+                    $archivesInfo['add_time'] = getTime();
264
+                    $archivesInfo['update_time'] = getTime();
265
+                    $archivesData[] = $archivesInfo;
266
+                }
267
+                if (!empty($archivesData)) {
268
+                    $rdata = model('Archives')->saveAll($archivesData);
269
+                    if ($rdata) {
270
+                        // 内容扩展表的数据
271
+                        $contentData = [];
272
+                        $contentInfo = $contentRow[$val['aid']];
273
+
274
+                        // 拥有特性模型的其他数据处理
275
+                        $imgUploadInfo = $imgUploadData = [];
276
+                        $downloadFileInfo = $downloadFileData = [];
277
+                        $mediaFileInfo = $mediaFileData = [];
278
+                        $specialNodeInfo = $specialNodeData = [];
279
+                        $productAttrInfo = $productImgInfo = $productNetdiskInfo = $productSpecInfo = $productSpecValueInfo = [];
280
+                        $productAttrData = $productImgData = $productNetdiskData = $productSpecData = $productSpecValueData = [];
281
+                        if ('images' == $channeltypeRow['nid']) { // 图集模型的特性表数据
282
+                            $imgUploadInfo = !empty($imgUploadRow[$val['aid']]) ? $imgUploadRow[$val['aid']] : [];
283
+                        } else if ('download' == $channeltypeRow['nid']) { // 下载模型的特性表数据
284
+                            $downloadFileInfo = !empty($downloadFileRow[$val['aid']]) ? $downloadFileRow[$val['aid']] : [];
285
+                        } else if ('product' == $channeltypeRow['nid']) { // 新房模型的特性表数据
286
+                            // 属性值表 - 只复制同栏目的属性值
287
+                            if ($typeid_old == $typeid) {
288
+                                $productAttrInfo = !empty($productAttrRow[$val['aid']]) ? $productAttrRow[$val['aid']] : [];
289
+                            }
290
+                            // 产品图集表
291
+                            $productImgInfo = !empty($productImgRow[$val['aid']]) ? $productImgRow[$val['aid']] : [];
292
+                            // 产品虚拟表
293
+                            $productNetdiskInfo = !empty($productNetdiskRow[$val['aid']]) ? $productNetdiskRow[$val['aid']] : [];
294
+                            // 产品规格数据表
295
+                            $productSpecInfo = !empty($productSpecRow[$val['aid']]) ? $productSpecRow[$val['aid']] : [];
296
+                            // 产品多规格组装表
297
+                            $productSpecValueInfo = !empty($productSpecValueRow[$val['aid']]) ? $productSpecValueRow[$val['aid']] : [];
298
+                        } else if ('media' == $channeltypeRow['nid']) { // 视频模型的特性表数据
299
+                            $mediaFileInfo = !empty($mediaFileRow[$val['aid']]) ? $mediaFileRow[$val['aid']] : [];
300
+                        } else if ('special' == $channeltypeRow['nid']) { // 专题模型的特性表数据
301
+                            $specialNodeInfo = !empty($specialNodeRow[$val['aid']]) ? $specialNodeRow[$val['aid']] : [];
302
+                        }
303
+
304
+                        // 需要复制的数据与新产生的文档ID进行关联
305
+                        foreach ($rdata as $k1 => $v1) {
306
+                            $aid_new = $v1->getData('aid');
307
+
308
+                            // 内容扩展表的数据
309
+                            $contentInfo['aid'] = $aid_new;
310
+                            $contentData[] = $contentInfo;
311
+
312
+                            // 图集模型
313
+                            if ('images' == $channeltypeRow['nid']) {
314
+                                foreach ($imgUploadInfo as $img_k => $img_v) {
315
+                                    $img_v['aid'] = $aid_new;
316
+                                    $imgUploadData[] = $img_v;
317
+                                }
318
+                            } else if ('download' == $channeltypeRow['nid']) {
319
+                                // 附件表
320
+                                foreach ($downloadFileInfo as $file_k => $file_v) {
321
+                                    $file_v['aid'] = $aid_new;
322
+                                    $downloadFileData[] = $file_v;
323
+                                }
324
+                            } else if ('product' == $channeltypeRow['nid']) {
325
+                                // 属性值表
326
+                                foreach ($productAttrInfo as $attr_k => $attr_v) {
327
+                                    $attr_v['aid'] = $aid_new;
328
+                                    $productAttrData[] = $attr_v;
329
+                                }
330
+                                // 产品图集表
331
+                                foreach ($productImgInfo as $img_k => $img_v) {
332
+                                    $img_v['aid'] = $aid_new;
333
+                                    $productImgData[] = $img_v;
334
+                                }
335
+                                // 产品虚拟表
336
+                                foreach ($productNetdiskInfo as $nd_k => $nd_v) {
337
+                                    $nd_v['aid'] = $aid_new;
338
+                                    $productNetdiskData[] = $nd_v;
339
+                                }
340
+                                // 产品规格数据表
341
+                                foreach ($productSpecInfo as $spec_k => $spec_v) {
342
+                                    $spec_v['aid'] = $aid_new;
343
+                                    $productSpecData[] = $spec_v;
344
+                                }
345
+                                // 产品多规格组装表
346
+                                foreach ($productSpecValueInfo as $specv_k => $specv_v) {
347
+                                    $specv_v['aid'] = $aid_new;
348
+                                    $productSpecValueData[] = $specv_v;
349
+                                }
350
+                            } else if ('media' == $channeltypeRow['nid']) {
351
+                                // 附件表
352
+                                foreach ($mediaFileInfo as $file_k => $file_v) {
353
+                                    $file_v['aid'] = $aid_new;
354
+                                    $mediaFileData[] = $file_v;
355
+                                }
356
+                            } else if ('special' == $channeltypeRow['nid']) {
357
+                                // 附件表
358
+                                foreach ($specialNodeInfo as $node_k => $node_v) {
359
+                                    $node_v['aid'] = $aid_new;
360
+                                    $specialNodeData[] = $node_v;
361
+                                }
362
+                            }
363
+                        }
364
+
365
+                        // 批量写入内容扩展表
366
+                        if (!empty($contentData)) {
367
+                            Db::name($tableExt)->insertAll($contentData);
368
+                        }
369
+                        // 批量写入图集模型的图片表
370
+                        if ('images' == $channeltypeRow['nid']) {
371
+                            !empty($imgUploadData) && model('ImagesUpload')->saveAll($imgUploadData);
372
+                        } else if ('download' == $channeltypeRow['nid']) {
373
+                            // 附件表
374
+                            !empty($downloadFileData) && model('DownloadFile')->saveAll($downloadFileData);
375
+                        } else if ('product' == $channeltypeRow['nid']) {
376
+                            // 属性值表
377
+                            !empty($productAttrData) && Db::name('product_attr')->insertAll($productAttrData);
378
+                            // 产品图集表
379
+                            !empty($productImgData) && model('ProductImg')->saveAll($productImgData);
380
+                            // 产品虚拟表
381
+                            !empty($productNetdiskData) && model('ProductNetdisk')->saveAll($productNetdiskData);
382
+                            // 产品规格数据表
383
+                            !empty($productSpecData) && model('ProductSpecData')->saveAll($productSpecData);
384
+                            // 产品多规格组装表
385
+                            !empty($productSpecValueData) && model('ProductSpecValue')->saveAll($productSpecValueData);
386
+                        } else if ('media' == $channeltypeRow['nid']) {
387
+                            // 附件表
388
+                            !empty($mediaFileData) && model('MediaFile')->saveAll($mediaFileData);
389
+                        } else if ('special' == $channeltypeRow['nid']) {
390
+                            // 附件表
391
+                            !empty($specialNodeData) && model('SpecialNode')->saveAll($specialNodeData);
392
+                        }
393
+                    }
394
+                    else {
395
+                        $this->error('复制失败!');
396
+                    }
397
+                }
398
+            }
399
+            /*清空sql_cache_table数据缓存表 并 添加查询执行语句到mysql缓存表*/
400
+            Db::name('sql_cache_table')->execute('TRUNCATE TABLE '.config('database.prefix').'sql_cache_table');
401
+            model('SqlCacheTable')->InsertSqlCacheTable(true);
402
+            /* END */
403
+            $this->success('复制成功!');
404
+        } else {
405
+            $this->error('模型不存在!');
406
+        }
407
+    }
408
+
409
+    /**
410
+     * 复制全部文档
411
+     * 新增语言是复制使用
412
+     * 从中文复制到新增的语言
413
+     * $is_jump = 0 不跳过重复文章 1 - 跳过
414
+     */
415
+    public function batch_copy_all($lang = '',$is_jump = 0)
416
+    {
417
+        if (empty($lang)) return false;
418
+        //删除已有数据 开始
419
+        $lang_channel_data = Db::name('archives')
420
+            ->alias('a')
421
+            ->field('a.channel,b.nid,b.table')
422
+            ->join('channeltype b','a.channel = b.id','left')
423
+            ->where(['a.lang' => $lang, 'a.is_del' => 0,'a.channel'=>['neq',6]])
424
+            ->group('a.channel')
425
+            ->getAllWithIndex('channel');
426
+        if (!empty($lang_channel_data)){
427
+            foreach ($lang_channel_data as $k => $v){
428
+                $aids = Db::name('archives')->where(['lang' => $lang, 'is_del' => 0,'channel'=>$v['channel']])->column('aid');
429
+                Db::name('archives')->where(['aid' => ['IN', $aids]])->delete();
430
+
431
+                //删除内容扩展表
432
+                $tableExt = $v['table'] . "_content";
433
+                Db::name($tableExt)->where(['aid' => ['IN', $aids]])->delete();
434
+
435
+                // 拥有特性模型的其他数据处理
436
+                if ('images' == $v['nid']) {
437
+                    $imgUploadRow = Db::name('images_upload')->where(['aid' => ['IN', $aids]])->delete();
438
+                } else if ('download' == $v['nid']) { // 下载模型的特性表数据
439
+                    // 附件表
440
+                    $downloadFileRow = Db::name('download_file')->where(['aid' => ['IN', $aids]])->delete();
441
+                } else if ('product' == $v['nid']) { // 产品模型的特性表数据
442
+                    // 属性值表
443
+                    $productAttrRow = Db::name('product_attr')->where(['aid' => ['IN', $aids]])->delete();
444
+                    // 产品图集表
445
+                    $productImgRow = Db::name('product_img')->where(['aid' => ['IN', $aids]])->delete();
446
+                    // 产品虚拟表
447
+                    $productNetdiskRow = Db::name('product_netdisk')->where(['aid' => ['IN', $aids]])->delete();
448
+                    // 产品规格数据表
449
+                    $productSpecRow = Db::name('product_spec_data')->where(['aid' => ['IN', $aids]])->delete();
450
+                    // 产品多规格组装表
451
+                    $productSpecValueRow = Db::name('product_spec_value')->where(['aid' => ['IN', $aids]])->delete();
452
+                } else if ('media' == $v['nid']) { // 视频模型的特性表数据
453
+                    // 附件表
454
+                    $mediaFileRow = Db::name('media_file')->where(['aid' => ['IN', $aids]])->delete();
455
+                } else if ('special' == $v['nid']) { // 专题模型的特性表数据
456
+                    // 节点表
457
+                    $specialNodeRow = Db::name('special_node')->where(['aid' => ['IN', $aids]])->delete();
458
+                }
459
+            }
460
+        }
461
+        //删除已有数据 结束
462
+
463
+        //新建数据开始
464
+        $channel_ids = Db::name('archives')->where(['lang' => 'cn', 'is_del' => 0,'channel'=>['neq',6]])->group('channel')->column('channel');
465
+        // 获取复制栏目的模型ID
466
+        $channeltypeRow = Db::name('channeltype')->field('id,nid,table')
467
+            ->where([
468
+                'id' => ['in', $channel_ids],
469
+            ])->getAllWithIndex('id');
470
+
471
+        if (!empty($channeltypeRow)) {
472
+            $error_aid = [];
473
+            foreach ($channeltypeRow as $k => $v) {
474
+                $archivesRow = Db::name('archives')->where(['lang' => 'cn', 'is_del' => 0,'channel'=>$k])->select();
475
+                if (!empty($is_jump)){
476
+                    $titles = get_arr_column($archivesRow,'title');
477
+                    $repeat_title_arr = Db::name('archives')->where(['lang' => $lang, 'is_del' => 0,'channel'=>$k])->where('title','in',$titles)->column('title');
478
+                    if (!empty($repeat_title_arr)){
479
+                        foreach ($archivesRow as $m => $n){
480
+                            if (in_array($n['title'],$repeat_title_arr)) unset($archivesRow[$m]);
481
+                        }
482
+                        if (!empty($archivesRow)) {
483
+                            $archivesRow = array_merge($archivesRow);
484
+                        }
485
+                    }
486
+                }
487
+                if (empty($archivesRow)) continue;
488
+                $aids = $typeids = [];
489
+                foreach ($archivesRow as $key => $val) {
490
+                    if (!in_array($val['aid'], $aids)) $aids[] = $val['aid'];
491
+                    if (!in_array($val['typeid'], $typeids)) $typeids[] = $val['typeid'];
492
+                }
493
+                // 内容扩展表数据
494
+                $tableExt = $v['table'] . "_content";
495
+                $contentRow = Db::name($tableExt)->field('id', true)->where(['aid' => ['IN', $aids]])->getAllWithIndex('aid');
496
+                // 原语言栏目
497
+                $typeids_arr = [];
498
+                foreach ($typeids as $key => $val){
499
+                    $typeids_arr[] = 'tid' . $val;
500
+                }
501
+                // 源语言关联的多语言栏目
502
+                $lang_typeids = Db::name('language_attr')->where(['attr_group' => 'arctype', 'attr_name' => ['in',$typeids_arr],'lang'=>$lang])->field('attr_value,attr_name')->getAllWithIndex('attr_name');
503
+                // 拥有特性模型的其他数据处理
504
+                if ('images' == $v['nid']) { // 图集模型的特性表数据
505
+                    $imgUploadRow = Db::name('images_upload')->field('img_id', true)->where(['aid' => ['IN', $aids]])->select();
506
+                    $imgUploadRow = group_same_key($imgUploadRow, 'aid');
507
+                } else if ('download' == $v['nid']) { // 下载模型的特性表数据
508
+                    // 附件表
509
+                    $downloadFileRow = Db::name('download_file')->field('file_id', true)->where(['aid' => ['IN', $aids]])->select();
510
+                    $downloadFileRow = group_same_key($downloadFileRow, 'aid');
511
+                } else if ('product' == $v['nid']) { // 产品模型的特性表数据
512
+                    // 属性值表
513
+                    $productAttrRow = Db::name('product_attr')->field('product_attr_id', true)->where(['aid' => ['IN', $aids]])->select();
514
+                    $productAttrRow = group_same_key($productAttrRow, 'aid');
515
+                    // 产品图集表
516
+                    $productImgRow = Db::name('product_img')->field('img_id', true)->where(['aid' => ['IN', $aids]])->select();
517
+                    $productImgRow = group_same_key($productImgRow, 'aid');
518
+                    // 产品虚拟表
519
+                    $productNetdiskRow = Db::name('product_netdisk')->field('nd_id', true)->where(['aid' => ['IN', $aids]])->select();
520
+                    $productNetdiskRow = group_same_key($productNetdiskRow, 'aid');
521
+                    // 产品规格数据表
522
+                    $productSpecRow = Db::name('product_spec_data')->field('spec_id', true)->where(['aid' => ['IN', $aids]])->select();
523
+                    $productSpecRow = group_same_key($productSpecRow, 'aid');
524
+                    // 产品多规格组装表
525
+                    $productSpecValueRow = Db::name('product_spec_value')->field('value_id', true)->where(['aid' => ['IN', $aids]])->select();
526
+                    $productSpecValueRow = group_same_key($productSpecValueRow, 'aid');
527
+                } else if ('media' == $v['nid']) { // 视频模型的特性表数据
528
+                    // 附件表
529
+                    $mediaFileRow = Db::name('media_file')->field('file_id', true)->where(['aid' => ['IN', $aids]])->select();
530
+                    $mediaFileRow = group_same_key($mediaFileRow, 'aid');
531
+                } else if ('special' == $v['nid']) { // 专题模型的特性表数据
532
+                    // 节点表
533
+                    $specialNodeRow = Db::name('special_node')->field('node_id', true)->where(['aid' => ['IN', $aids]])->select();
534
+                    $specialNodeRow = group_same_key($specialNodeRow, 'aid');
535
+                }
536
+
537
+                foreach ($archivesRow as $key => $val) {
538
+                    // 原先数据的栏目ID
539
+                    $typeid_old = $val['typeid'];
540
+                    //多语言栏目id
541
+                    $typeid =  $lang_typeids['tid'.$val['typeid']]['attr_value'];
542
+                    // 只同步相关联的栏目
543
+                    if (empty($typeid)) {
544
+                        continue;
545
+                    }
546
+                    $aid = $val['aid'];
547
+                    $archivesInfo = $val;
548
+                    unset($archivesInfo['aid']);
549
+                    $archivesInfo['typeid'] = $typeid;
550
+                    $archivesInfo['lang'] = $lang;
551
+                    // $archivesInfo['add_time'] = getTime();
552
+                    // $archivesInfo['update_time'] = getTime();
553
+
554
+                    if (!empty($archivesInfo)) {
555
+                        $new_aid = Db::name('archives')->insertGetId($archivesInfo);
556
+                        if ($new_aid) {
557
+                            $channelfield_bind_list = Db::name('channelfield_bind')->where('typeid',$typeid_old)->select();
558
+                            if (!empty($channelfield_bind_list)){
559
+                                $field_ids = get_arr_column($channelfield_bind_list,'field_id');
560
+                                //查询已经写入的
561
+                                $bind_field_ids = Db::name('channelfield_bind')->where('typeid',$typeid)->where('field_id','in',$field_ids)->column('field_id');
562
+                                $channelfield_bind_insert = [];
563
+                                foreach ($channelfield_bind_list as $k => $v) {
564
+                                    //已经写入的不在写入
565
+                                    if (!in_array($v['field_id'], $bind_field_ids)){
566
+                                        $channelfield_bind_insert[] = [
567
+                                            'typeid' => $typeid,
568
+                                            'field_id' => $v['field_id'],
569
+                                            'add_time' => getTime(),
570
+                                            'update_time' => getTime()
571
+                                        ];
572
+                                    }
573
+                                }
574
+                                //写入绑定自定义字段
575
+                                Db::name('channelfield_bind')->insertAll($channelfield_bind_insert);
576
+                            }
577
+
578
+                            // 内容扩展表的数据
579
+                            $contentInfo = $contentRow[$val['aid']];
580
+                            $contentInfo['aid'] = $new_aid;
581
+
582
+                            // 拥有特性模型的其他数据处理
583
+                            $imgUploadInfo = $imgUploadData = [];
584
+                            $downloadFileInfo = $downloadFileData = [];
585
+                            $mediaFileInfo = $mediaFileData = [];
586
+                            $specialNodeInfo = $specialNodeData = [];
587
+                            $productAttrInfo = $productImgInfo = $productNetdiskInfo = $productSpecInfo = $productSpecValueInfo = [];
588
+                            $productAttrData = $productImgData = $productNetdiskData = $productSpecData = $productSpecValueData = [];
589
+                            if ('images' == $v['nid']) { // 图集模型的特性表数据
590
+                                $imgUploadInfo = !empty($imgUploadRow[$val['aid']]) ? $imgUploadRow[$val['aid']] : [];
591
+                            } else if ('download' == $v['nid']) { // 下载模型的特性表数据
592
+                                $downloadFileInfo = !empty($downloadFileRow[$val['aid']]) ? $downloadFileRow[$val['aid']] : [];
593
+                            } else if ('product' == $v['nid']) { // 新房模型的特性表数据
594
+                                // 属性值表 - 只复制同栏目的属性值
595
+                                if ($typeid_old == $typeid) {
596
+                                    $productAttrInfo = !empty($productAttrRow[$val['aid']]) ? $productAttrRow[$val['aid']] : [];
597
+                                }
598
+                                // 产品图集表
599
+                                $productImgInfo = !empty($productImgRow[$val['aid']]) ? $productImgRow[$val['aid']] : [];
600
+                                // 产品虚拟表
601
+                                $productNetdiskInfo = !empty($productNetdiskRow[$val['aid']]) ? $productNetdiskRow[$val['aid']] : [];
602
+                                // 产品规格数据表
603
+                                $productSpecInfo = !empty($productSpecRow[$val['aid']]) ? $productSpecRow[$val['aid']] : [];
604
+                                // 产品多规格组装表
605
+                                $productSpecValueInfo = !empty($productSpecValueRow[$val['aid']]) ? $productSpecValueRow[$val['aid']] : [];
606
+                            } else if ('media' == $v['nid']) { // 视频模型的特性表数据
607
+                                $mediaFileInfo = !empty($mediaFileRow[$val['aid']]) ? $mediaFileRow[$val['aid']] : [];
608
+                            } else if ('special' == $v['nid']) { // 专题模型的特性表数据
609
+                                $specialNodeInfo = !empty($specialNodeRow[$val['aid']]) ? $specialNodeRow[$val['aid']] : [];
610
+                            }
611
+
612
+                            // 图集模型
613
+                            if ('images' == $v['nid']) {
614
+                                foreach ($imgUploadInfo as $img_k => $img_v) {
615
+                                    $img_v['aid'] = $new_aid;
616
+                                    $imgUploadData[] = $img_v;
617
+                                }
618
+                            } else if ('download' == $v['nid']) {
619
+                                // 附件表
620
+                                foreach ($downloadFileInfo as $file_k => $file_v) {
621
+                                    $file_v['aid'] = $new_aid;
622
+                                    $downloadFileData[] = $file_v;
623
+                                }
624
+                            } else if ('product' == $v['nid']) {
625
+                                // 属性值表
626
+                                foreach ($productAttrInfo as $attr_k => $attr_v) {
627
+                                    $attr_v['aid'] = $new_aid;
628
+                                    $productAttrData[] = $attr_v;
629
+                                }
630
+                                // 产品图集表
631
+                                foreach ($productImgInfo as $img_k => $img_v) {
632
+                                    $img_v['aid'] = $new_aid;
633
+                                    $productImgData[] = $img_v;
634
+                                }
635
+                                // 产品虚拟表
636
+                                foreach ($productNetdiskInfo as $nd_k => $nd_v) {
637
+                                    $nd_v['aid'] = $new_aid;
638
+                                    $productNetdiskData[] = $nd_v;
639
+                                }
640
+                                // 产品规格数据表
641
+                                foreach ($productSpecInfo as $spec_k => $spec_v) {
642
+                                    $spec_v['aid'] = $new_aid;
643
+                                    $productSpecData[] = $spec_v;
644
+                                }
645
+                                // 产品多规格组装表
646
+                                foreach ($productSpecValueInfo as $specv_k => $specv_v) {
647
+                                    $specv_v['aid'] = $new_aid;
648
+                                    $productSpecValueData[] = $specv_v;
649
+                                }
650
+                            } else if ('media' == $v['nid']) {
651
+                                // 附件表
652
+                                foreach ($mediaFileInfo as $file_k => $file_v) {
653
+                                    $file_v['aid'] = $new_aid;
654
+                                    $mediaFileData[] = $file_v;
655
+                                }
656
+                            } else if ('special' == $v['nid']) {
657
+                                // 附件表
658
+                                foreach ($specialNodeInfo as $node_k => $node_v) {
659
+                                    $node_v['aid'] = $new_aid;
660
+                                    $specialNodeData[] = $node_v;
661
+                                }
662
+                            }
663
+
664
+                            // 批量写入内容扩展表
665
+                            if (!empty($contentInfo)) {
666
+                                Db::name($tableExt)->insert($contentInfo);
667
+                            }
668
+                            // 批量写入图集模型的图片表
669
+                            if ('images' == $v['nid']) {
670
+                                !empty($imgUploadData) && model('ImagesUpload')->saveAll($imgUploadData);
671
+                            } else if ('download' == $v['nid']) {
672
+                                // 附件表
673
+                                !empty($downloadFileData) && model('DownloadFile')->saveAll($downloadFileData);
674
+                            } else if ('product' == $v['nid']) {
675
+                                // 属性值表
676
+                                !empty($productAttrData) && Db::name('product_attr')->insertAll($productAttrData);
677
+                                // 产品图集表
678
+                                !empty($productImgData) && model('ProductImg')->saveAll($productImgData);
679
+                                // 产品虚拟表
680
+                                !empty($productNetdiskData) && model('ProductNetdisk')->saveAll($productNetdiskData);
681
+                                // 产品规格数据表
682
+                                !empty($productSpecData) && model('ProductSpecData')->saveAll($productSpecData);
683
+                                // 产品多规格组装表
684
+                                !empty($productSpecValueData) && model('ProductSpecValue')->saveAll($productSpecValueData);
685
+                            } else if ('media' == $v['nid']) {
686
+                                // 附件表
687
+                                !empty($mediaFileData) && model('MediaFile')->saveAll($mediaFileData);
688
+                            } else if ('special' == $v['nid']) {
689
+                                // 附件表
690
+                                !empty($specialNodeData) && model('SpecialNode')->saveAll($specialNodeData);
691
+                            }
692
+                        } else {
693
+                            $error_aid[] = $aid;
694
+                            adminLog("文档{$aid}复制失败");
695
+                        }
696
+                    }
697
+                }
698
+            }
699
+
700
+            //同步栏目内容
701
+            $single_arc = Db::name('archives')->where(['lang' => 'cn', 'is_del' => 0,'channel'=>6])->select();
702
+            $lang_single_arc = Db::name('archives')->where(['lang' => $lang, 'is_del' => 0,'channel'=>6])->field('aid,typeid')->getAllWithIndex('typeid');
703
+            if (!empty($single_arc)){
704
+                $aids = get_arr_column($single_arc,'aid');
705
+                $typeids = get_arr_column($single_arc,'typeid');
706
+                $contentRow = Db::name('single_content')->field('id', true)->where(['aid' => ['IN', $aids]])->getAllWithIndex('aid');
707
+                $typeids_arr = [];
708
+                foreach ($typeids as $key => $val){
709
+                    $typeids_arr[] = 'tid' . $val;
710
+                }
711
+                $lang_typeids = Db::name('language_attr')->where(['attr_group' => 'arctype', 'attr_name' => ['in',$typeids_arr],'lang'=>$lang])->field('attr_value,attr_name')->getAllWithIndex('attr_name');
712
+
713
+                foreach ($contentRow as $key => $val) {
714
+                    //多语言栏目id
715
+                    $typeid = $lang_typeids['tid' . $val['typeid']]['attr_value'];
716
+                    $lang_aid = $lang_single_arc[$typeid]['aid'];
717
+                    Db::name('single_content')->where('aid',$lang_aid)->update(['content'=>$val['content'],'content_ey_m'=>$val['content_ey_m']]);
718
+                }
719
+            }
720
+
721
+            /*清空sql_cache_table数据缓存表 并 添加查询执行语句到mysql缓存表*/
722
+            Db::name('sql_cache_table')->execute('TRUNCATE TABLE ' . config('database.prefix') . 'sql_cache_table');
723
+            model('SqlCacheTable')->InsertSqlCacheTable(true);
724
+            /* END */
725
+        }
726
+        return true;
727
+    }
728
+
729
+    public function getRestricTypeText($restricType = 0)
730
+    {
731
+        $restricTypeText = '免费';
732
+        if (1 === intval($restricType)) {
733
+            $restricTypeText = '付费';
734
+        } else if (2 === intval($restricType)) {
735
+            $restricTypeText = '指定会员';
736
+        } else if (3 === intval($restricType)) {
737
+            $restricTypeText = '会员付费';
738
+        }
739
+        return $restricTypeText;
740
+    }
741
+}

+ 530
- 0
application/admin/logic/AskLogic.php View File

@@ -0,0 +1,530 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Model;
17
+use think\Db;
18
+
19
+/**
20
+ * 逻辑定义
21
+ * Class CatsLogic
22
+ * @package admin\Logic
23
+ */
24
+class AskLogic extends Model
25
+{
26
+    private $request = null;
27
+    private $data_path;
28
+    private $service_url;
29
+    private $upgrade_url;
30
+    private $service_ey;
31
+    private $planPath_pc;
32
+    private $planPath_m;
33
+
34
+    /**
35
+     * 析构函数
36
+     */
37
+    function  __construct() {
38
+        $this->request = request();
39
+        $this->service_ey = config('service_ey');
40
+        $this->data_path = DATA_PATH; // 
41
+        // api_Service_checkVersion
42
+        $tmp_str = 'L2luZGV4LnBocD9tPWFwaSZjPVVwZ3JhZGUmYT1jaGVja1RoZW1lVmVyc2lvbg==';
43
+        $this->service_url = base64_decode($this->service_ey).base64_decode($tmp_str);
44
+        $web_basehost = request()->host(true);
45
+        if (false !== filter_var($web_basehost, FILTER_VALIDATE_IP)) {
46
+            $web_basehost = tpCache('web.web_basehost');
47
+        }
48
+        $web_basehost = preg_replace('/^(http(s)?:)?(\/\/)?([^\/\:]*)(.*)$/i', '${4}', $web_basehost);
49
+        $this->upgrade_url = $this->service_url . '&domain='.$web_basehost.'&type=theme_ask&cms_version='.getVersion().'&ip='.serverIP();
50
+        $this->planPath_pc = 'template/'.TPL_THEME.'pc/';
51
+        $this->planPath_m = 'template/'.TPL_THEME.'mobile/';
52
+    }
53
+
54
+    /**
55
+     * 检测并第一次从官方同步问答中心的前台模板
56
+     */
57
+    public function syn_theme_ask()
58
+    {
59
+        error_reporting(0);//关闭所有错误报告
60
+        if (!file_exists("{$this->planPath_pc}ask")) {
61
+            return $this->OneKeyUpgrade();
62
+        } else {
63
+            return true;
64
+        }
65
+    }
66
+
67
+    /**
68
+     * 检测目录权限
69
+     */
70
+    public function checkAuthority($filelist = '')
71
+    {
72
+        /*------------------检测目录读写权限----------------------*/
73
+        $filelist = htmlspecialchars_decode($filelist);
74
+        $filelist = explode('<br>', $filelist);
75
+
76
+        $dirs = array();
77
+        $i = -1;
78
+        foreach($filelist as $filename)
79
+        {
80
+            if (stristr($filename, $this->planPath_pc) && !file_exists($this->planPath_pc)) {
81
+                continue;
82
+            } else if (stristr($filename, $this->planPath_m) && !file_exists($this->planPath_m)) {
83
+                continue;
84
+            }
85
+
86
+            $tfilename = $filename;
87
+            $curdir = $this->GetDirName($tfilename);
88
+            if (empty($curdir)) {
89
+                continue;
90
+            }
91
+            if( !isset($dirs[$curdir]) ) 
92
+            {
93
+                $dirs[$curdir] = $this->TestIsFileDir($curdir);
94
+            }
95
+            if($dirs[$curdir]['isdir'] == FALSE) 
96
+            {
97
+                continue;
98
+            }
99
+            else {
100
+                $dirs[$curdir] = $this->TestIsFileDir($curdir);
101
+            }
102
+            $i++;
103
+        }
104
+
105
+        $is_pass = true;
106
+        $msg = '检测通过';
107
+        if($i > -1)
108
+        {
109
+            $n = 0;
110
+            $dirinfos = '';
111
+            foreach($dirs as $curdir)
112
+            {
113
+                $dirinfos .= $curdir['name']."&nbsp;&nbsp;状态:";
114
+                if ($curdir['writeable']) {
115
+                    $dirinfos .= "[√正常]";
116
+                } else {
117
+                    $is_pass = false;
118
+                    $n++;
119
+                    $dirinfos .= "<font color='red'>[×不可写]</font>";
120
+                }
121
+                $dirinfos .= "<br />";
122
+            }
123
+            $title = "本次升级需要在下面文件夹写入更新文件,已检测站点有 <font color='red'>{$n}</font> 处没有写入权限:<br />";
124
+            $title .= "<font color='red'>问题分析(如有问题,请咨询技术支持):<br />";
125
+            $title .= "1、检查站点目录的用户组与所有者,禁止是 root ;<br />";
126
+            $title .= "2、检查站点目录的读写权限,一般权限值是 0755 ;<br />";
127
+            $title .= "</font>涉及更新目录列表如下:<br />";
128
+            $msg = $title . $dirinfos;
129
+        }
130
+        /*------------------end----------------------*/
131
+
132
+        if (true === $is_pass) {
133
+            return ['code'=>1, 'msg'=>$msg];
134
+        } else {
135
+            return ['code'=>0, 'msg'=>$msg, 'data'=>['code'=>1]];
136
+        }
137
+    }
138
+
139
+    /**
140
+     * 检查是否有更新包
141
+     * @return type 提示语
142
+     */
143
+    public function checkVersion() {
144
+        //error_reporting(0);//关闭所有错误报告     
145
+        $allow_url_fopen = ini_get('allow_url_fopen');
146
+        if (!$allow_url_fopen) {
147
+            return ['code' => 1, 'msg' => "<font color='red'>请联系空间商(设置 php.ini 中参数 allow_url_fopen = 1)</font>"];
148
+        }
149
+
150
+        $url = $this->upgrade_url; 
151
+        $serviceVersionList = @httpRequest($url);
152
+        if (false === $serviceVersionList) {
153
+            $context = stream_context_set_default(array('http' => array('timeout' => 3,'method'=>'GET')));
154
+            $serviceVersionList = @file_get_contents($url,false,$context); 
155
+        } 
156
+        $serviceVersionList = json_decode($serviceVersionList,true);
157
+        if(!empty($serviceVersionList))
158
+        {
159
+            $upgradeArr = array();
160
+            $introStr = '';
161
+            $upgradeStr = '';
162
+            foreach ($serviceVersionList as $key => $val) {
163
+                $upgrade = !empty($val['upgrade']) ? $val['upgrade'] : array();
164
+                $upgradeArr = array_merge($upgradeArr, $upgrade);
165
+                $introStr .= '<br>'.filter_line_return($val['intro'], '<br>');
166
+            }
167
+            $upgradeArr = array_unique($upgradeArr);
168
+            foreach ($upgradeArr as $key => $val) {
169
+                if (stristr($val, $this->planPath_pc) && !file_exists($this->planPath_pc)) {
170
+                    unset($upgradeArr[$key]);
171
+                } else if (stristr($val, $this->planPath_m) && !file_exists($this->planPath_m)) {
172
+                    unset($upgradeArr[$key]);
173
+                }
174
+            }
175
+            $upgradeStr = implode('<br>', $upgradeArr); // 升级提示需要覆盖哪些文件
176
+
177
+            $introArr = explode('<br>', $introStr);
178
+            $introStr = '更新日志:';
179
+            foreach ($introArr as $key => $val) {
180
+                if (empty($val)) {
181
+                    continue;
182
+                }
183
+                $introStr .= "<br>{$key}、".$val;
184
+            }
185
+
186
+            $lastupgrade = $serviceVersionList[count($serviceVersionList) - 1];
187
+            if (!empty($lastupgrade['upgrade_title'])) {
188
+                $introStr .= '<br>'.$lastupgrade['upgrade_title'];
189
+            }
190
+            $lastupgrade['intro'] = htmlspecialchars_decode($introStr);
191
+            $lastupgrade['upgrade'] = htmlspecialchars_decode($upgradeStr); // 升级提示需要覆盖哪些文件
192
+            /*升级公告*/
193
+            if (!empty($lastupgrade['notice'])) {
194
+                $lastupgrade['notice'] = htmlspecialchars_decode($lastupgrade['notice']) . '<br>';
195
+            }
196
+            /*--end*/
197
+
198
+            return ['code' => 2, 'msg' => $lastupgrade];
199
+        }
200
+        return ['code' => 1, 'msg' => '已是最新版'];
201
+    }
202
+
203
+    /**
204
+     * 检查是否有更新包
205
+     * @return type 提示语
206
+     */
207
+    public function OneKeyUpgrade() {
208
+        $allow_url_fopen = ini_get('allow_url_fopen');
209
+        if (!$allow_url_fopen) {
210
+            return ['code' => 0, 'msg' => "请联系空间商,设置 php.ini 中参数 allow_url_fopen = 1"];
211
+        }     
212
+               
213
+        if (!extension_loaded('zip')) {
214
+            return ['code' => 0, 'msg' => "请联系空间商,开启 php.ini 中的php-zip扩展"];
215
+        }
216
+
217
+        $serviceVersionList = @httpRequest($this->upgrade_url);
218
+        if (false === $serviceVersionList) {
219
+            $serviceVersionList = @file_get_contents($this->upgrade_url); 
220
+        }
221
+        $serviceVersionList = json_decode($serviceVersionList,true);
222
+        if (empty($serviceVersionList)) {
223
+            return ['code' => 0, 'msg' => "没找到模板包信息"];
224
+        } else if (isset($serviceVersionList['code']) && empty($serviceVersionList['code'])) {
225
+            $icon = !empty($serviceVersionList['icon']) ? $serviceVersionList['icon'] : 2;
226
+            return ['code' => 0, 'msg' => $serviceVersionList['msg'], 'icon'=>$icon];
227
+        }
228
+        
229
+        /*最新更新版本信息*/
230
+        $lastServiceVersion = $serviceVersionList[count($serviceVersionList) - 1];
231
+        /*--end*/
232
+        /*批量下载更新包*/
233
+        $upgradeArr = array(); // 更新的文件列表
234
+        $folderName = 'ask-'.$lastServiceVersion['key_num'];
235
+        foreach ($serviceVersionList as $key => $val) {
236
+            // 下载更新包
237
+            $result = $this->downloadFile($val['down_url'], $val['file_md5']);
238
+            if (!isset($result['code']) || $result['code'] != 1) {
239
+                return $result;
240
+            }
241
+
242
+            /*第一个循环执行的业务*/
243
+            if ($key == 0) {
244
+                /*解压到最后一个更新包的文件夹*/
245
+                $lastDownFileName = explode('/', $lastServiceVersion['down_url']);    
246
+                $lastDownFileName = end($lastDownFileName);
247
+                $folderName = 'ask-'.str_replace(".zip", "", $lastDownFileName);  // 文件夹
248
+                /*--end*/
249
+
250
+                /*解压之前,删除已重复的文件夹*/
251
+                delFile($this->data_path.'backup'.DS.'theme'.DS.$folderName);
252
+                /*--end*/
253
+            }
254
+            /*--end*/
255
+
256
+            $downFileName = explode('/', $val['down_url']);    
257
+            $downFileName = 'ask-'.end($downFileName);
258
+
259
+            /*解压文件*/
260
+            $zip = new \ZipArchive();//新建一个ZipArchive的对象
261
+            if ($zip->open($this->data_path.'backup'.DS.'theme'.DS.$downFileName) != true) {
262
+                return ['code' => 0, 'msg' => "模板包读取失败!"];
263
+            }
264
+            $zip->extractTo($this->data_path.'backup'.DS.'theme'.DS.$folderName.DS);//假设解压缩到在当前路径下backup文件夹内
265
+            $zip->close();//关闭处理的zip文件
266
+            /*--end*/
267
+
268
+            /*更新的文件列表*/
269
+            $upgrade = !empty($val['upgrade']) ? $val['upgrade'] : array();
270
+            $upgradeArr = array_merge($upgradeArr, $upgrade);
271
+            /*--end*/
272
+        }
273
+        /*--end*/
274
+
275
+        /*将多个更新包重新组建一个新的完全更新包*/
276
+        $upgradeArr = array_unique($upgradeArr); // 移除文件列表里重复的文件
277
+        $serviceVersion = $lastServiceVersion;
278
+        $serviceVersion['upgrade'] = $upgradeArr;
279
+        /*--end*/
280
+
281
+        /*升级之前,备份涉及的源文件*/
282
+        $upgrade = $serviceVersion['upgrade'];
283
+        if (!empty($upgrade) && is_array($upgrade)) {
284
+            foreach ($upgrade as $key => $val) {
285
+                $source_file = ROOT_PATH.$val;
286
+                if (file_exists($source_file)) {
287
+                    $destination_file = $this->data_path.'backup'.DS.'theme'.DS.$folderName.'_www'.DS.$val;
288
+                    tp_mkdir(dirname($destination_file));
289
+                    $copy_bool = @copy($source_file, $destination_file);
290
+                    if (false == $copy_bool) {
291
+                        return ['code' => 0, 'msg' => "备份文件失败,请检查所有目录是否有读写权限"];
292
+                    }
293
+                }
294
+            }
295
+        }
296
+        /*--end*/
297
+
298
+        // 递归复制文件夹
299
+        $copy_data = $this->recurse_copy($this->data_path.'backup'.DS.'theme'.DS.$folderName, rtrim(ROOT_PATH, DS), $folderName);
300
+
301
+        /*删除下载的模板包*/
302
+        $ziplist = glob($this->data_path.'backup'.DS.'theme'.DS.'ask-*.zip');
303
+        @array_map('unlink', $ziplist);
304
+        /*--end*/
305
+
306
+        // 推送回服务器  记录升级成功
307
+        $this->UpgradeLog($serviceVersion['key_num']);
308
+        
309
+        return ['code' => $copy_data['code'], 'msg' => "更新模板成功{$copy_data['msg']}"];
310
+    }
311
+
312
+    /**
313
+     * 自定义函数递归的复制带有多级子目录的目录
314
+     * 递归复制文件夹
315
+     *
316
+     * @param string $src 原目录
317
+     * @param string $dst 复制到的目录
318
+     * @param string $folderName 存放升级包目录名称
319
+     * @return string
320
+     */                        
321
+    //参数说明:            
322
+    //自定义函数递归的复制带有多级子目录的目录
323
+    private function recurse_copy($src, $dst, $folderName)
324
+    {
325
+        static $badcp = 0; // 累计覆盖失败的文件总数
326
+        static $n = 0; // 累计执行覆盖的文件总数
327
+        static $total = 0; // 累计更新的文件总数
328
+
329
+        $dir = opendir($src);
330
+
331
+        /*pc和mobile目录存在的情况下,才拷贝会员模板到相应的pc或mobile里*/
332
+        $dst_tmp = str_replace('\\', '/', $dst);
333
+        $dst_tmp = rtrim($dst_tmp, '/').'/';
334
+        if (stristr($dst_tmp, $this->planPath_pc) && file_exists($this->planPath_pc)) {
335
+            tp_mkdir($dst);
336
+        } else if (stristr($dst_tmp, $this->planPath_m) && file_exists($this->planPath_m)) {
337
+            tp_mkdir($dst);
338
+        }
339
+        /*--end*/
340
+
341
+        while (false !== $file = readdir($dir)) {
342
+            if (($file != '.') && ($file != '..')) {
343
+                if (is_dir($src . '/' . $file)) {
344
+                    $needle = '/template/'.TPL_THEME;
345
+                    $needle = rtrim($needle, '/');
346
+                    $dstfile = $dst . '/' . $file;
347
+                    if (!stristr($dstfile, $needle)) {
348
+                        $dstfile = str_replace('/template', $needle, $dstfile);
349
+                    }
350
+                    $this->recurse_copy($src . '/' . $file, $dstfile, $folderName);
351
+                }
352
+                else {
353
+                    if (file_exists($src . DIRECTORY_SEPARATOR . $file)) {
354
+                        /*pc和mobile目录存在的情况下,才拷贝会员模板到相应的pc或mobile里*/
355
+                        $rs = true;
356
+                        $src_tmp = str_replace('\\', '/', $src . DIRECTORY_SEPARATOR . $file);
357
+                        if (stristr($src_tmp, $this->planPath_pc) && !file_exists($this->planPath_pc)) {
358
+                            continue;
359
+                        } else if (stristr($src_tmp, $this->planPath_m) && !file_exists($this->planPath_m)) {
360
+                            continue;
361
+                        }
362
+                        /*--end*/
363
+                        $rs = @copy($src . DIRECTORY_SEPARATOR . $file, $dst . DIRECTORY_SEPARATOR . $file);
364
+                        if($rs) {
365
+                            $n++;
366
+                            @unlink($src . DIRECTORY_SEPARATOR . $file);
367
+                        } else {
368
+                            $n++;
369
+                            $badcp++;
370
+                        }
371
+                    } else {
372
+                        $n++;
373
+                    }
374
+                    $total++;
375
+                }
376
+            }
377
+        }
378
+        closedir($dir);
379
+
380
+        $code = 1;
381
+        $msg = '!';
382
+        if($badcp > 0)
383
+        {
384
+            $code = 2;
385
+            $msg = ",其中失败 <font color='red'>{$badcp}</font> 个文件,<br />请从模板包目录[<font color='red'>data/backup/theme/{$folderName}</font>]中的取出全部文件覆盖到根目录,完成手工覆盖。";
386
+        }
387
+
388
+        $this->copy_speed($n, $total);
389
+
390
+        return ['code'=>$code, 'msg'=>$msg];
391
+    }
392
+
393
+    /**
394
+     * 复制文件进度
395
+     */
396
+    private function copy_speed($n, $total)
397
+    {
398
+        $data = false;
399
+
400
+        if ($n < $total) {
401
+            $this->copy_speed($n, $total);
402
+        } else {
403
+            $data = true;
404
+        }
405
+        
406
+        return $data;
407
+    }
408
+ 
409
+    /**     
410
+     * @param type $fileUrl 下载文件地址
411
+     * @param type $md5File 文件MD5 加密值 用于对比下载是否完整
412
+     * @return string 错误或成功提示
413
+     */
414
+    private function downloadFile($fileUrl,$md5File)
415
+    {
416
+        $downFileName = explode('/', $fileUrl);   
417
+        $downFileName = 'ask-'.end($downFileName);
418
+        $saveDir = $this->data_path.'backup'.DS.'theme'.DS.$downFileName; // 保存目录
419
+        tp_mkdir(dirname($saveDir));
420
+        $content = @httpRequest($fileUrl);
421
+        if (false === $content) {
422
+            $content = @file_get_contents($fileUrl, 0, null, 0, 1);
423
+        }
424
+
425
+        if(!$content){
426
+            return ['code' => 0, 'msg' => '官方问答模板包不存在']; // 文件存在直接退出
427
+        }
428
+
429
+        if (!stristr($fileUrl, 'https://service')) {
430
+            $ch = curl_init($fileUrl);
431
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
432
+            curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
433
+            $file = curl_exec ($ch);
434
+            curl_close ($ch);
435
+        } else {
436
+            $file = httpRequest($fileUrl);
437
+        }
438
+
439
+        if (preg_match('#__HALT_COMPILER()#i', $file)) {
440
+            return ['code' => 0, 'msg' => '问答模板包损坏,请联系官方客服!'];
441
+        }
442
+                                                            
443
+        $fp = fopen($saveDir,'w');
444
+        fwrite($fp, $file);
445
+        fclose($fp);
446
+        if(!eyPreventShell($saveDir) || !file_exists($saveDir) || $md5File != md5_file($saveDir))
447
+        {
448
+            return ['code' => 0, 'msg' => '下载保存问答模板包失败,请检查所有目录的权限以及用户组不能为root'];
449
+        }
450
+        return ['code' => 1, 'msg' => '下载成功'];
451
+    }                
452
+    
453
+    // 升级记录 log 日志
454
+    private  function UpgradeLog($to_key_num){
455
+        $serial_number = DEFAULT_SERIALNUMBER;
456
+
457
+        $constsant_path = APP_PATH.MODULE_NAME.'/conf/constant.php';
458
+        if (file_exists($constsant_path)) {
459
+            require_once($constsant_path);
460
+            defined('SERIALNUMBER') && $serial_number = SERIALNUMBER;
461
+        }
462
+        $mysqlinfo = \think\Db::query("SELECT VERSION() as version");
463
+        $mysql_version  = $mysqlinfo[0]['version'];
464
+        $values = array(
465
+            'type'  => 'theme_ask',
466
+            'domain'=>request()->host(), //用户域名                
467
+            'key_num'=>'v1.0.0', // 用户版本号
468
+            'to_key_num'=>$to_key_num, // 用户要升级的版本号                
469
+            'add_time'=>time(), // 升级时间
470
+            'serial_number'=>$serial_number,
471
+            'ip'    => GetHostByName($_SERVER['SERVER_NAME']),
472
+            'phpv'  => phpversion(),
473
+            'mysql_version' => $mysql_version,
474
+            'web_server'    => $_SERVER['SERVER_SOFTWARE'],
475
+        );
476
+        // api_Service_upgradeLog
477
+        $tmp_str = 'L2luZGV4LnBocD9tPWFwaSZjPVVwZ3JhZGUmYT11cGdyYWRlTG9nJg==';
478
+        $url = base64_decode($this->service_ey).base64_decode($tmp_str).http_build_query($values);
479
+        @httpRequest($url);
480
+    }
481
+
482
+    /**
483
+     * 获取文件的目录路径
484
+     * @param string $filename 文件路径+文件名
485
+     * @return string
486
+     */
487
+    private function GetDirName($filename)
488
+    {
489
+        $dirname = preg_replace("#[\\\\\/]{1,}#", '/', $filename);
490
+        $dirname = preg_replace("#([^\/]*)$#", '', $dirname);
491
+        return $dirname;
492
+    }
493
+
494
+    /**
495
+     * 测试目录路径是否有读写权限
496
+     * @param string $dirname 文件目录路径
497
+     * @return array
498
+     */
499
+    private function TestIsFileDir($dirname)
500
+    {
501
+        $dirs = array('name'=>'', 'isdir'=>FALSE, 'writeable'=>FALSE);
502
+        $dirs['name'] =  $dirname;
503
+        tp_mkdir($dirname);
504
+        if(is_dir($dirname))
505
+        {
506
+            $dirs['isdir'] = TRUE;
507
+            $dirs['writeable'] = $this->TestWriteAble($dirname);
508
+        }
509
+        return $dirs;
510
+    }
511
+
512
+    /**
513
+     * 测试目录路径是否有写入权限
514
+     * @param string $d 目录路劲
515
+     * @return boolean
516
+     */
517
+    private function TestWriteAble($d)
518
+    {
519
+        $tfile = '_eyout.txt';
520
+        $fp = @fopen($d.$tfile,'w');
521
+        if(!$fp) {
522
+            return false;
523
+        }
524
+        else {
525
+            fclose($fp);
526
+            $rs = @unlink($d.$tfile);
527
+            return true;
528
+        }
529
+    }
530
+}

+ 63
- 0
application/admin/logic/DiyExtendLogic.php View File

@@ -0,0 +1,63 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3 
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Model;
17
+use think\Db;
18
+use think\Request;
19
+
20
+/**
21
+ * 逻辑定义
22
+ * Class CatsLogic
23
+ * @package admin\Logic
24
+ */
25
+class DiyExtendLogic extends Model
26
+{
27
+    private $request = null; // 当前Request对象实例
28
+    private $admin_lang = 'cn'; // 后台多语言标识
29
+
30
+    /**
31
+     * 析构函数
32
+     */
33
+    function  __construct() {
34
+        null === $this->request && $this->request = Request::instance();
35
+        $this->admin_lang = get_admin_lang();
36
+    }
37
+
38
+    /**
39
+     * 获取当前页面所在的模型ID
40
+     * @param string $id 模型ID
41
+     */
42
+    public function getChannelid()
43
+    {
44
+        $channeltype = input('param.channeltype/d', 0);
45
+        $channel = input('param.channel/d', $channeltype);
46
+        if (!empty($channel)) {
47
+            return $channel;
48
+        }
49
+
50
+        $controller_name = input('param.controller_name/s', '');
51
+        if (empty($controller_name)) {
52
+            $controller_name = $this->request->controller();
53
+        }
54
+        
55
+        if ('Custom' != $controller_name) {
56
+            $channel = Db::name('channeltype')->where([
57
+                    'ctl_name'  => $controller_name,
58
+                ])->getField('id');
59
+        }
60
+
61
+        return $channel;
62
+    }
63
+}

+ 1035
- 0
application/admin/logic/EyouCmsLogic.php
File diff suppressed because it is too large
View File


+ 750
- 0
application/admin/logic/FieldLogic.php View File

@@ -0,0 +1,750 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Model;
17
+use think\Db;
18
+/**
19
+ * 字段逻辑定义
20
+ * Class CatsLogic
21
+ * @package admin\Logic
22
+ */
23
+class FieldLogic extends Model
24
+{
25
+    /**
26
+     * 获得字段创建信息
27
+     *
28
+     * @access    public
29
+     * @param     string  $dtype  字段类型
30
+     * @param     string  $fieldname  字段名称
31
+     * @param     string  $dfvalue  默认值
32
+     * @param     string  $fieldtitle  字段标题
33
+     * @return    array
34
+     */
35
+    function GetFieldMake($dtype, $fieldname, $dfvalue, $fieldtitle)
36
+    {
37
+        $fields = array();
38
+        if("int" == $dtype)
39
+        {
40
+            empty($dfvalue) && $dfvalue = 0;
41
+            $default_sql = '';
42
+            if(preg_match("#[0-9]+#", $dfvalue))
43
+            {
44
+                $default_sql = "DEFAULT '$dfvalue'";
45
+            }
46
+            $maxlen = 10;
47
+            $fields[0] = " `$fieldname` int($maxlen) NOT NULL $default_sql COMMENT '$fieldtitle';";
48
+            $fields[1] = "int($maxlen)";
49
+            $fields[2] = $maxlen;
50
+        }
51
+        else if("datetime" == $dtype)
52
+        {
53
+            empty($dfvalue) && $dfvalue = 0;
54
+            $default_sql = '';
55
+            if(preg_match("#[0-9\-]+#", $dfvalue))
56
+            {
57
+                $dfvalue = strtotime($dfvalue);
58
+                empty($dfvalue) && $dfvalue = 0;
59
+                $default_sql = "DEFAULT '$dfvalue'";
60
+            }
61
+            $maxlen = 11;
62
+            $fields[0] = " `$fieldname` int($maxlen) NOT NULL $default_sql COMMENT '$fieldtitle';";
63
+            $fields[1] = "int($maxlen)";
64
+            $fields[2] = $maxlen;
65
+        }
66
+        else if("switch" == $dtype)
67
+        {
68
+            if(empty($dfvalue) || preg_match("#[^0-9]+#", $dfvalue))
69
+            {
70
+                $dfvalue = 1;
71
+            }
72
+            $maxlen = 1;
73
+            $fields[0] = " `$fieldname` tinyint($maxlen) NOT NULL DEFAULT '$dfvalue' COMMENT '$fieldtitle';";
74
+            $fields[1] = "tinyint($maxlen)";
75
+            $fields[2] = $maxlen;
76
+        }
77
+        else if("float" == $dtype)
78
+        {
79
+            empty($dfvalue) && $dfvalue = 0;
80
+            $default_sql = '';
81
+            if(preg_match("#[0-9\.]+#", $dfvalue))
82
+            {
83
+                $default_sql = "DEFAULT '$dfvalue'";
84
+            }
85
+            $maxlen = 9;
86
+            $fields[0] = " `$fieldname` float($maxlen,2) NOT NULL $default_sql COMMENT '$fieldtitle';";
87
+            $fields[1] = "float($maxlen,2)";
88
+            $fields[2] = $maxlen;
89
+        }
90
+        else if("decimal" == $dtype)
91
+        {
92
+            empty($dfvalue) && $dfvalue = 0;
93
+            $default_sql = '';
94
+            if(preg_match("#[0-9\.]+#", $dfvalue))
95
+            {
96
+                $default_sql = "DEFAULT '$dfvalue'";
97
+            }
98
+            $maxlen = 10;
99
+            $fields[0] = " `$fieldname` decimal($maxlen,2) NOT NULL $default_sql COMMENT '$fieldtitle';";
100
+            $fields[1] = "decimal($maxlen,2)";
101
+            $fields[2] = $maxlen;
102
+        }
103
+        else if("img" == $dtype)
104
+        {
105
+            if(empty($dfvalue)) {
106
+                $dfvalue = '';
107
+            }
108
+            $maxlen = 500;
109
+            $fields[0] = " `$fieldname` varchar($maxlen) NOT NULL DEFAULT '$dfvalue' COMMENT '$fieldtitle';";
110
+            $fields[1] = "varchar($maxlen)";
111
+            $fields[2] = $maxlen;
112
+        }
113
+        else if("imgs" == $dtype)
114
+        {
115
+            if(empty($dfvalue)) {
116
+                $dfvalue = '';
117
+            }
118
+            $maxlen = 10001;
119
+            $fields[0] = " `$fieldname` text COMMENT '$fieldtitle|{$maxlen}';";
120
+            $fields[1] = "text";
121
+            $fields[2] = $maxlen;
122
+        }
123
+        else if("media" == $dtype)
124
+        {
125
+            $maxlen = 500;
126
+            $fields[0] = " `$fieldname` varchar($maxlen) NOT NULL DEFAULT '$dfvalue' COMMENT '$fieldtitle';";
127
+            $fields[1] = "varchar($maxlen)";
128
+            $fields[2] = $maxlen;
129
+        }
130
+        else if("files" == $dtype)
131
+        {
132
+            if(empty($dfvalue)) {
133
+                $dfvalue = '';
134
+            }
135
+            $maxlen = 10002;
136
+            $fields[0] = " `$fieldname` text COMMENT '$fieldtitle|{$maxlen}';";
137
+            $fields[1] = "text";
138
+            $fields[2] = $maxlen;
139
+        }
140
+        else if("multitext" == $dtype)
141
+        {
142
+            $maxlen = 0;
143
+            $fields[0] = " `$fieldname` text COMMENT '$fieldtitle';";
144
+            $fields[1] = "text";
145
+            $fields[2] = $maxlen;
146
+        }
147
+        else if("htmltext" == $dtype)
148
+        {
149
+            $maxlen = 0;
150
+            $fields[0] = " `$fieldname` longtext CHARACTER SET utf8 COMMENT '$fieldtitle';";
151
+            $fields[1] = "longtext";
152
+            $fields[2] = $maxlen;
153
+        }
154
+        else if("checkbox" == $dtype)
155
+        {
156
+            $maxlen = 0;
157
+            $dfvalueArr = explode(',', $dfvalue);
158
+            if (64 < count($dfvalueArr)){
159
+                $dfvalueArr = array_slice($dfvalueArr, 0, 64);
160
+                $dfvalue = implode(',', $dfvalueArr);
161
+            }
162
+            $default_value = '';
163
+            // $default_value = !empty($dfvalueArr[0]) ? $dfvalueArr[0] : '';
164
+            $dfvalue = str_replace(',', "','", $dfvalue);
165
+            $dfvalue = "'".$dfvalue."'";
166
+            $fields[0] = " `$fieldname` SET($dfvalue) NULL DEFAULT '{$default_value}' COMMENT '$fieldtitle';";
167
+            $fields[1] = "SET($dfvalue)";
168
+            $fields[2] = $maxlen;
169
+        }
170
+        else if("select" == $dtype || "radio" == $dtype)
171
+        {
172
+            $maxlen = 0;
173
+            $dfvalueArr = explode(',', $dfvalue);
174
+            $default_value = !empty($dfvalueArr[0]) ? $dfvalueArr[0] : '';
175
+            $dfvalue = str_replace(',', "','", $dfvalue);
176
+            $dfvalue = "'".$dfvalue."'";
177
+            $fields[0] = " `$fieldname` enum($dfvalue) NULL DEFAULT '{$default_value}' COMMENT '$fieldtitle';";
178
+            $fields[1] = "enum($dfvalue)";
179
+            $fields[2] = $maxlen;
180
+        }
181
+        else
182
+        {
183
+            if(empty($dfvalue))
184
+            {
185
+                $dfvalue = '';
186
+            }
187
+            $maxlen = 500;
188
+            $fields[0] = " `$fieldname` varchar($maxlen) NOT NULL DEFAULT '$dfvalue' COMMENT '$fieldtitle';";
189
+            $fields[1] = "varchar($maxlen)";
190
+            $fields[2] = $maxlen;
191
+        }
192
+
193
+        return $fields;
194
+    }
195
+
196
+    /**
197
+     * 检测频道模型相关的表字段是否已存在,包括:主表和附加表
198
+     *
199
+     * @access    public
200
+     * @param     string  $slave_table  附加表
201
+     * @return    string $fieldname 字段名
202
+     * @return    int $channel_id 模型ID
203
+     * @param     array  $filter  过滤哪些字段
204
+     */
205
+    public function checkChannelFieldList($slave_table, $fieldname, $channel_id, $filter = array())
206
+    {
207
+        // 栏目表字段
208
+        $arctypeFieldArr = Db::getTableFields(PREFIX.'arctype'); 
209
+        foreach ($arctypeFieldArr as $key => $val) {
210
+            if (!preg_match('/^type/i',$val)) {
211
+                array_push($arctypeFieldArr, 'type'.$val);
212
+            }
213
+        }
214
+        $masterFieldArr = Db::getTableFields(PREFIX.'archives'); // 文档主表字段
215
+        $slaveFieldArr = Db::getTableFields($slave_table); // 文档附加表字段
216
+        $addfields = ['pageurl','has_children','typelitpic','arcurl','typeurl']; // 额外与字段冲突的变量名
217
+        $fieldArr = array_merge($slaveFieldArr, $masterFieldArr, $addfields, $arctypeFieldArr); // 合并字段
218
+        if (!empty($fieldname)) {
219
+            if (!empty($filter) && is_array($filter)) {
220
+                foreach ($filter as $key => $val) {
221
+                    $k = array_search($val, $fieldArr);
222
+                    if (false !== $k) {
223
+                        unset($fieldArr[$k]);
224
+                    }
225
+                }
226
+            }
227
+            return in_array($fieldname, $fieldArr);
228
+        }
229
+
230
+        return true;
231
+    }
232
+
233
+    /**
234
+     * 检测指定表的字段是否已存在
235
+     *
236
+     * @access    public
237
+     * @param     string  $table  数据表
238
+     * @return    string $fieldname 字段名
239
+     * @param     array  $filter  过滤哪些字段
240
+     */
241
+    public function checkTableFieldList($table, $fieldname, $filter = array())
242
+    {
243
+        $fieldArr = Db::getTableFields($table); // 表字段
244
+        if (!empty($fieldname)) {
245
+            if (!empty($filter) && is_array($filter)) {
246
+                foreach ($filter as $key => $val) {
247
+                    $k = array_search($val, $fieldArr);
248
+                    if (false !== $k) {
249
+                        unset($fieldArr[$k]);
250
+                    }
251
+                }
252
+            }
253
+            return in_array($fieldname, $fieldArr);
254
+        }
255
+
256
+        return true;
257
+    }
258
+
259
+    /**
260
+     * 删除指定模型的表字段
261
+     * @param int $id channelfield表ID
262
+     * @return bool
263
+     */
264
+    public function delChannelField($id)
265
+    {
266
+        $code = 0;
267
+        $msg = '参数有误!';
268
+        if (!empty($id)) {
269
+            $id = intval($id);
270
+            $row = model('Channelfield')->getInfo($id, 'channel_id,name,ifsystem');
271
+            if (!empty($row['ifsystem'])) {
272
+                return array('code'=>0, 'msg'=>'禁止删除系统字段!');
273
+            }
274
+            $fieldname = $row['name'];
275
+            $channel_id = $row['channel_id'];
276
+            $table = Db::name('channeltype')->where('id',$channel_id)->getField('table');
277
+            $table = PREFIX.$table.'_content';
278
+            if ($this->checkChannelFieldList($table, $fieldname, $channel_id)) {
279
+                $sql = "ALTER TABLE `{$table}` DROP COLUMN `{$fieldname}`;";
280
+                if(false !== Db::execute($sql)) {
281
+                    /*重新生成数据表字段缓存文件*/
282
+                    try {
283
+                        schemaTable($table);
284
+                    } catch (\Exception $e) {}
285
+                    /*--end*/
286
+                    return array('code'=>1, 'msg'=>'删除成功!');
287
+                } else {
288
+                    $code = 0;
289
+                    $msg = '删除失败!'; 
290
+                }
291
+            } else {
292
+                $code = 2;
293
+                $msg = '字段不存在!';
294
+            }
295
+        }
296
+
297
+        return array('code'=>$code, 'msg'=>$msg);
298
+    }
299
+
300
+    /**
301
+     * 删除栏目的表字段
302
+     * @param int $id channelfield表ID
303
+     * @return bool
304
+     */
305
+    public function delArctypeField($id)
306
+    {
307
+        $code = 0;
308
+        $msg = '参数有误!';
309
+        if (!empty($id)) {
310
+            $id = intval($id);
311
+            $row = model('Channelfield')->getInfo($id, 'name,ifsystem');
312
+            if (!empty($row['ifsystem'])) {
313
+                return array('code'=>0, 'msg'=>'禁止删除系统字段!');
314
+            }
315
+            $fieldname = $row['name'];
316
+            $table = PREFIX.'arctype';
317
+            if ($this->checkTableFieldList($table, $fieldname)) {
318
+                $sql = "ALTER TABLE `{$table}` DROP COLUMN `{$fieldname}`;";
319
+                if(false !== Db::execute($sql)) {
320
+                    /*重新生成数据表字段缓存文件*/
321
+                    try {
322
+                        schemaTable($table);
323
+                    } catch (\Exception $e) {}
324
+                    /*--end*/
325
+                    return array('code'=>1, 'msg'=>'删除成功!');
326
+                } else {
327
+                    $code = 0;
328
+                    $msg = '删除失败!'; 
329
+                }
330
+            } else {
331
+                $code = 2;
332
+                $msg = '字段不存在!';
333
+            }
334
+        }
335
+
336
+        return array('code'=>$code, 'msg'=>$msg);
337
+    }
338
+
339
+    /**
340
+     * 同步模型附加表的字段记录
341
+     * @author 小虎哥 by 2018-4-16
342
+     */
343
+    public function synChannelTableColumns($channel_id)
344
+    {
345
+        $this->synArchivesTableColumns($channel_id);
346
+        $channelfieldArr = Db::name('channelfield')->field('name,dtype')->where('channel_id',$channel_id)->getAllWithIndex('name');
347
+        $new_arr = array(); // 表字段数组
348
+        $addData = array(); // 数据存储变量
349
+
350
+        $table = Db::name('channeltype')->where('id',$channel_id)->getField('table');
351
+        $tableExt = PREFIX.$table.'_content';
352
+        $rowExt = Db::query("SHOW FULL COLUMNS FROM {$tableExt}");
353
+        foreach ($rowExt as $key => $val) {
354
+            $fieldname = $val['Field'];
355
+            if (in_array($fieldname, array('id','add_time','update_time','aid','typeid'))) {
356
+                continue;
357
+            }
358
+            $new_arr[] = $fieldname;
359
+            // 对比字段记录 表字段有 字段新增记录没有
360
+            if (empty($channelfieldArr[$fieldname])) {
361
+                $ifcontrol = 0;
362
+                $is_release = 0;
363
+                $ifeditable = 1;
364
+                $dtype = $this->toDtype($val['Type'], $val['Comment']);
365
+                $dfvalue = $this->toDefault($val['Type'], $val['Default']);
366
+                if (in_array($fieldname, array('content'))) {
367
+                    $ifsystem = 1;
368
+                } else {
369
+                    $ifsystem = 0;
370
+                }
371
+                $maxlength = preg_replace('/^([^\(]+)\(([^\)]+)\)(.*)/i', '$2', $val['Type']);
372
+                $maxlength = intval($maxlength);
373
+
374
+                /*视频模型附加表内置的系统字段*/
375
+                if (5 == $channel_id && in_array($fieldname, ['total_video','total_duration','courseware_free','courseware'])) {
376
+                    $ifsystem = 1;
377
+                    $ifcontrol = 1;
378
+                    $is_release = 1;
379
+                    $ifeditable = 0;
380
+                } else if ($channel_id <= 8 || (50 <= $channel_id && $channel_id <= 100)) {
381
+                    if ('content' == $fieldname) {
382
+                        $is_release = 1;
383
+                    }
384
+                }
385
+                /*end*/
386
+
387
+                $addData[] = array(
388
+                    'name'  => $fieldname,
389
+                    'channel_id'  => $channel_id,
390
+                    'title'  => !empty($val['Comment']) ? $val['Comment'] : $fieldname,
391
+                    'dtype' => $dtype,
392
+                    'define'    => $val['Type'],
393
+                    'maxlength' => $maxlength,
394
+                    'dfvalue'   => $dfvalue,
395
+                    'is_release'    => $is_release,
396
+                    'ifeditable'    => $ifeditable,
397
+                    'ifsystem'  => $ifsystem,
398
+                    'ifmain'    => 0,
399
+                    'ifcontrol' => $ifcontrol,
400
+                    'add_time'  => getTime(),
401
+                    'update_time'  => getTime(),
402
+                );
403
+            }
404
+        }
405
+        if (!empty($addData)) {
406
+            Db::name('channelfield')->insertAll($addData);
407
+        }
408
+
409
+        /*字段新增记录有,表字段没有*/
410
+        foreach($channelfieldArr as $k => $v){
411
+            if (!in_array($k, $new_arr)) {
412
+                $map = array(
413
+                    'channel_id'    => $channel_id,
414
+                    'ifmain'    => 0,
415
+                    'name'  => $v['name'],
416
+                );
417
+                Db::name('channelfield')->where($map)->delete();
418
+            }
419
+        }
420
+        /*--end*/
421
+
422
+        \think\Cache::clear('channelfield');
423
+    }
424
+
425
+    /**
426
+     * 同步文档主表的字段记录到指定模型
427
+     * @author 小虎哥 by 2018-4-16
428
+     */
429
+    public function synArchivesTableColumns($channel_id = '')
430
+    {
431
+        $channelfieldArr = Db::name('channelfield')->field('name,dtype')->where('channel_id',$channel_id)->getAllWithIndex('name');
432
+
433
+        $new_arr = array(); // 表字段数组
434
+        $addData = array(); // 数据存储变量
435
+
436
+        $controlFields = ['litpic','author'];
437
+        $channeltype_system_ids = Db::name('channeltype')->where([
438
+                'ifsystem'  => 1,
439
+            ])->column('id');
440
+
441
+        $table = PREFIX.'archives';
442
+        $row = Db::query("SHOW FULL COLUMNS FROM {$table}");
443
+        $row = array_reverse($row);
444
+        foreach ($row as $key => $val) {
445
+            $fieldname = $val['Field'];
446
+            $new_arr[] = $fieldname;
447
+            // 对比字段记录 表字段有 字段新增记录没有
448
+            if (empty($channelfieldArr[$fieldname])) {
449
+                $dtype = $this->toDtype($val['Type'], $val['Comment']);
450
+                $dfvalue = $this->toDefault($val['Type'], $val['Default']);
451
+                if (in_array($fieldname, $controlFields) && !in_array($channel_id, $channeltype_system_ids)) {
452
+                    $ifcontrol = 0;
453
+                } else {
454
+                    $ifcontrol = 1;
455
+                }
456
+                $maxlength = preg_replace('/^([^\(]+)\(([^\)]+)\)(.*)/i', '$2', $val['Type']);
457
+                $maxlength = intval($maxlength);
458
+                $addData[] = array(
459
+                    'name'  => $fieldname,
460
+                    'channel_id'  => $channel_id,
461
+                    'title'  => !empty($val['Comment']) ? $val['Comment'] : $fieldname,
462
+                    'dtype' => $dtype,
463
+                    'define'    => $val['Type'],
464
+                    'maxlength' => $maxlength,
465
+                    'dfvalue'   => $dfvalue,
466
+                    'ifeditable'    => 1,
467
+                    'ifsystem' => 1,
468
+                    'ifmain'    => 1,
469
+                    'ifcontrol' => $ifcontrol,
470
+                    'add_time'  => getTime(),
471
+                    'update_time'  => getTime(),
472
+                );
473
+            }
474
+        }
475
+        if (!empty($addData)) {
476
+            Db::name('channelfield')->insertAll($addData);
477
+        }
478
+
479
+        /*字段新增记录有,表字段没有*/
480
+        foreach($channelfieldArr as $k => $v){
481
+            if (!in_array($k, $new_arr)) {
482
+                $map = array(
483
+                    'channel_id'  => $channel_id,
484
+                    'ifmain'    => 1,
485
+                    'name'  => $v['name'],
486
+                );
487
+                Db::name('channelfield')->where($map)->delete();
488
+            }
489
+        }
490
+        /*--end*/
491
+    }
492
+
493
+    /**
494
+     * 同步栏目主表的字段记录
495
+     * @author 小虎哥 by 2018-4-16
496
+     */
497
+    public function synArctypeTableColumns($channel_id = '')
498
+    {
499
+        $cacheKey = md5("admin-FieldLogic-synArctypeTableColumns-{$channel_id}");
500
+        $cacheValue = cache($cacheKey);
501
+        if (!empty($cacheValue)) {
502
+            return true;
503
+        }
504
+
505
+        $channel_id = !empty($channel_id) ? $channel_id : config('global.arctype_channel_id');
506
+        $channelfieldArr = Db::name('channelfield')->field('name,dtype')->where('channel_id',$channel_id)->getAllWithIndex('name');
507
+
508
+        $new_arr = array(); // 表字段数组
509
+        $addData = array(); // 数据存储变量
510
+
511
+        $table = PREFIX.'arctype';
512
+        $row = Db::query("SHOW FULL COLUMNS FROM {$table}");
513
+        $row = array_reverse($row);
514
+        $arctypeTableFields = config('global.arctype_table_fields');
515
+        foreach ($row as $key => $val) {
516
+            $fieldname = $val['Field'];
517
+            $new_arr[] = $fieldname;
518
+            // 对比字段记录 表字段有 字段新增记录没有
519
+            if (empty($channelfieldArr[$fieldname])) {
520
+                $dtype = $this->toDtype($val['Type'], $val['Comment']);
521
+                $dfvalue = $this->toDefault($val['Type'], $val['Default']);
522
+                if (in_array($fieldname, $arctypeTableFields)) {
523
+                    $ifsystem = 1;
524
+                } else {
525
+                    $ifsystem = 0;
526
+                }
527
+                $maxlength = preg_replace('/^([^\(]+)\(([^\)]+)\)(.*)/i', '$2', $val['Type']);
528
+                $maxlength = intval($maxlength);
529
+                $addData[] = array(
530
+                    'name'  => $fieldname,
531
+                    'channel_id'  => $channel_id,
532
+                    'title'  => !empty($val['Comment']) ? $val['Comment'] : $fieldname,
533
+                    'dtype' => $dtype,
534
+                    'define'    => $val['Type'],
535
+                    'maxlength' => $maxlength,
536
+                    'dfvalue'   => $dfvalue,
537
+                    'ifeditable'    => 1,
538
+                    'ifsystem' => $ifsystem,
539
+                    'ifmain'    => 1,
540
+                    'ifcontrol' => 1,
541
+                    'add_time'  => getTime(),
542
+                    'update_time'  => getTime(),
543
+                );
544
+            }
545
+        }
546
+        if (!empty($addData)) {
547
+            Db::name('channelfield')->insertAll($addData);
548
+        }
549
+
550
+        /*字段新增记录有,表字段没有*/
551
+        foreach($channelfieldArr as $k => $v){
552
+            if (!in_array($k, $new_arr)) {
553
+                $map = array(
554
+                    'channel_id'  => $channel_id,
555
+                    'name'  => $v['name'],
556
+                );
557
+                Db::name('channelfield')->where($map)->delete();
558
+            }
559
+        }
560
+        /*--end*/
561
+
562
+        /*修复v1.1.9版本的admin_id为系统字段*/
563
+        Db::name('channelfield')->where('name','admin_id')->update(['ifsystem'=>1]);
564
+        /*--end*/
565
+
566
+        \think\Cache::clear('channelfield');
567
+        \think\Cache::clear("arctype");
568
+
569
+        cache($cacheKey, 1, null, 'channelfield');
570
+    }
571
+
572
+    /**
573
+     * 表字段类型转为自定义字段类型
574
+     * @author 小虎哥 by 2018-4-16
575
+     */
576
+    public function toDtype($fieldtype = '', $comment = '')
577
+    {
578
+        $commentArr = explode('|', $comment);
579
+        if (preg_match('/^int/i', $fieldtype)) {
580
+            $maxlen = preg_replace('/^int\((.*)\)/i', '$1', $fieldtype);
581
+            if (11 == $maxlen) {
582
+                $dtype = 'datetime';
583
+            } else {
584
+                $dtype = 'int';
585
+            }
586
+        } else if (preg_match('/^longtext/i', $fieldtype)) {
587
+            $dtype = 'htmltext';
588
+        } else if (preg_match('/^text/i', $fieldtype)) {
589
+            $maxlen = end($commentArr);
590
+            $maxlen = intval($maxlen);
591
+            if (1001 == $maxlen || 10001 == $maxlen) {
592
+                $dtype = 'imgs';
593
+            } else if (1002 == $maxlen || 10002 == $maxlen) {
594
+                $dtype = 'files';
595
+            } else {
596
+                $dtype = 'multitext';
597
+            }
598
+        } else if (preg_match('/^enum/i', $fieldtype)) {
599
+            $dtype = 'select';
600
+        } else if (preg_match('/^set/i', $fieldtype)) {
601
+            $dtype = 'checkbox';
602
+        } else if (preg_match('/^float/i', $fieldtype)) {
603
+            $dtype = 'float';
604
+        } else if (preg_match('/^decimal/i', $fieldtype)) {
605
+            $dtype = 'decimal';
606
+        } else if (preg_match('/^tinyint/i', $fieldtype)) {
607
+            $dtype = 'switch';
608
+        } else if (preg_match('/^varchar/i', $fieldtype)) {
609
+            $maxlen = preg_replace('/^varchar\((.*)\)/i', '$1', $fieldtype);
610
+            if (250 == $maxlen) {
611
+                $dtype = 'img';
612
+            } else if (1001 == $maxlen || 10001 == $maxlen) {
613
+                $dtype = 'imgs';
614
+            } else if (1002 == $maxlen || 10002 == $maxlen) {
615
+                $dtype = 'files';
616
+            } else {
617
+                $dtype = 'text';
618
+            }
619
+        } else {
620
+            $dtype = 'text';
621
+        }
622
+
623
+        return $dtype;
624
+    }
625
+
626
+    /**
627
+     * 表字段的默认值
628
+     * @author 小虎哥 by 2018-4-16
629
+     */
630
+    public function toDefault($fieldtype, $dfvalue = '')
631
+    {
632
+        if (preg_match('/^(enum|set)/i', $fieldtype)) {
633
+            $str = preg_replace('/^(enum|set)\((.*)\)/i', '$2', $fieldtype);
634
+            $str = str_replace("'", "", $str);
635
+        } else {
636
+            $str = $dfvalue;
637
+        }
638
+        $str = ("" != $str) ? $str : '';
639
+
640
+        return $str;
641
+    }
642
+
643
+    /**
644
+     * 处理栏目自定义字段的值
645
+     * @author 小虎哥 by 2018-4-16
646
+     */
647
+    public function handleAddonField($channel_id, $dataExt)
648
+    {
649
+        $nowDataExt = array();
650
+        if (!empty($dataExt) && !empty($channel_id)) {
651
+            $fieldTypeList = model('Channelfield')->getListByWhere(array('channel_id'=>$channel_id), 'name,dtype', 'name');
652
+            foreach ($dataExt as $key => $val) {
653
+                
654
+                $key = preg_replace('/^(.*)(_eyou_is_remote|_eyou_remote|_eyou_local)$/', '$1', $key);
655
+                $dtype = !empty($fieldTypeList[$key]) ? $fieldTypeList[$key]['dtype'] : '';
656
+                switch ($dtype) {
657
+
658
+                    case 'checkbox':
659
+                    {
660
+                        $val = implode(',', $val);
661
+                        break;
662
+                    }
663
+
664
+                    case 'switch':
665
+                    case 'int':
666
+                    {
667
+                        $val = intval($val);
668
+                        break;
669
+                    }
670
+
671
+                    case 'img':
672
+                    {
673
+                        $is_remote = !empty($dataExt[$key.'_eyou_is_remote']) ? $dataExt[$key.'_eyou_is_remote'] : 0;
674
+                        if (1 == $is_remote) {
675
+                            $val = $dataExt[$key.'_eyou_remote'];
676
+                        } else {
677
+                            $val = $dataExt[$key.'_eyou_local'];
678
+                        }
679
+                        break;
680
+                    }
681
+
682
+                    case 'imgs':
683
+                    {
684
+                        $imgData = [];
685
+                        $imgsIntroArr = !empty($dataExt[$key.'_eyou_intro']) ? $dataExt[$key.'_eyou_intro'] : [];
686
+                        foreach ($val as $k2 => $v2) {
687
+                            $v2 = trim($v2);
688
+                            if (!empty($v2)) {
689
+                                $imgData[] = [
690
+                                    'image_url' => $v2,
691
+                                    'intro'     => !empty($imgsIntroArr[$k2]) ? $imgsIntroArr[$k2] : '',
692
+                                ];
693
+                            }
694
+                        }
695
+                        $val = serialize($imgData);
696
+                        break;
697
+                    }
698
+
699
+                    case 'files':
700
+                    {
701
+                        foreach ($val as $k2 => $v2) {
702
+                            if (empty($v2)) {
703
+                                unset($val[$k2]);
704
+                                continue;
705
+                            }
706
+                            $val[$k2] = trim($v2);
707
+                        }
708
+                        $val = implode(',', $val);
709
+                        break;
710
+                    }
711
+
712
+                    case 'datetime':
713
+                    {
714
+                        $val = !empty($val) ? strtotime($val) : getTime();
715
+                        break;
716
+                    }
717
+
718
+                    case 'decimal':
719
+                    {
720
+                        $moneyArr = explode('.', $val);
721
+                        $money1 = !empty($moneyArr[0]) ? intval($moneyArr[0]) : '0';
722
+                        $money2 = !empty($moneyArr[1]) ? intval(msubstr($moneyArr[1], 0, 2)) : '00';
723
+                        $val = $money1.'.'.$money2;
724
+                        break;
725
+                    }
726
+                    
727
+                    default:
728
+                    {
729
+                        if (is_array($val)) {
730
+                            $new_val = [];
731
+                            foreach ($val as $_k => $_v) {
732
+                                $_v = trim($_v);
733
+                                if (!empty($_v)) {
734
+                                    $new_val[] = $_v;
735
+                                }
736
+                            }
737
+                            $val = $new_val;
738
+                        } else {
739
+                            $val = trim($val);
740
+                        }
741
+                        break;
742
+                    }
743
+                }
744
+                $nowDataExt[$key] = $val;
745
+            }
746
+        }
747
+
748
+        return $nowDataExt;
749
+    }
750
+}

+ 417
- 0
application/admin/logic/FilemanagerLogic.php View File

@@ -0,0 +1,417 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Model;
17
+use think\Db;
18
+/**
19
+ * 文件管理逻辑定义
20
+ * Class CatsLogic
21
+ * @package admin\Logic
22
+ */
23
+class FilemanagerLogic extends Model
24
+{
25
+    public $globalTpCache = array();
26
+    public $baseDir = ''; // 服务器站点根目录绝对路径
27
+    public $maxDir = '';
28
+    public $replaceImgOpArr = array(); // 替换权限
29
+    public $editOpArr = array(); // 编辑权限
30
+    public $renameOpArr = array(); // 改名权限
31
+    public $delOpArr = array(); // 删除权限
32
+    public $moveOpArr = array(); // 移动权限
33
+    public $editExt = array(); // 允许新增/编辑扩展名文件
34
+    public $disableFuns = array(); // 允许新增/编辑扩展名文件
35
+
36
+    /**
37
+     * 析构函数
38
+     */
39
+    function  __construct() {
40
+        $this->globalTpCache = tpCache('global');
41
+        $this->baseDir = rtrim(ROOT_PATH, DS); // 服务器站点根目录绝对路径
42
+        $this->maxDir = $this->globalTpCache['web_templets_dir']; // 默认文件管理的最大级别目录
43
+        // 替换权限
44
+        $this->replaceImgOpArr = array('gif','jpg','svg');
45
+        // 编辑权限
46
+        $this->editOpArr = array('txt','htm','js','css');
47
+        // 改名权限
48
+        $this->renameOpArr = array('dir','gif','jpg','svg','flash','zip','exe','mp3','wmv','rm','txt','htm','js','css','other');
49
+        // 删除权限
50
+        $this->delOpArr = array('dir','gif','jpg','svg','flash','zip','exe','mp3','wmv','rm','txt','htm','php','js','css','other');
51
+        // 移动权限
52
+        $this->moveOpArr = array('gif','jpg','svg','flash','zip','exe','mp3','wmv','rm','txt','htm','js','css','other');
53
+        // 允许新增/编辑扩展名文件
54
+        $this->editExt = array('htm','js','css','txt');
55
+        // 过滤php危险函数
56
+        $this->disableFuns = ['phpinfo'];
57
+    }
58
+
59
+    /**
60
+     * 编辑文件
61
+     *
62
+     * @access    public
63
+     * @param     string  $filename  文件名
64
+     * @param     string  $activepath  当前路径
65
+     * @param     string  $content  文件内容
66
+     * @return    string
67
+     */
68
+    public function editFile($filename, $activepath = '', $content = '')
69
+    {
70
+        $security = tpSetting('security');
71
+        if (empty($security['security_ask_open']) || empty($security['security_answer'])) {
72
+            return '需要开启密保问题设置';
73
+        } else {
74
+            $admin_id = session('?admin_id') ? (int)session('admin_id') : 0;
75
+            $admin_info = Db::name('admin')->field('admin_id,last_ip')->where(['admin_id'=>$admin_id])->find();
76
+            // 当前管理员二次安全验证过的IP地址
77
+            $security_answerverify_ip = !empty($security['security_answerverify_ip']) ? $security['security_answerverify_ip'] : '-1';
78
+            // 同IP不验证
79
+            if (empty($admin_info) || $admin_info['last_ip'] != $security_answerverify_ip) {
80
+                return '出于安全考虑,请勿非法越过密保答案验证';
81
+            }  
82
+        }
83
+
84
+        if (!filename_preg_match()) {
85
+            return '文件名称含有非法入侵字符!';
86
+        }
87
+
88
+        $fileinfo = pathinfo($filename);
89
+        $ext = strtolower($fileinfo['extension']);
90
+        $filename = trim($fileinfo['filename'], '.').'.'.$fileinfo['extension'];
91
+
92
+        /*不允许越过指定最大级目录的文件编辑*/
93
+        $tmp_max_dir = preg_replace("#\/#i", "\/", $this->maxDir);
94
+        if (!preg_match("#^".$tmp_max_dir."#i", $activepath)) {
95
+            return '没有操作权限!';
96
+        }
97
+        /*--end*/
98
+
99
+        /*允许编辑的文件类型*/
100
+        if (!in_array($ext, $this->editExt)) {
101
+            return '只允许操作文件类型如下:'.implode('|', $this->editExt);
102
+        }
103
+        /*--end*/
104
+
105
+        $file = $this->baseDir."$activepath/$filename";
106
+        if (!is_writable(dirname($file))) {
107
+            return "请把模板文件目录设置为可写入权限!";
108
+        }
109
+        if ('htm' == $ext) {
110
+            $content = htmlspecialchars_decode($content, ENT_QUOTES);
111
+            if (preg_match('#<([^?]*)\?php#i', $content) || preg_match('#<\?(\s*)=#i', $content) || (preg_match('#<\?#i', $content) && preg_match('#\?>#i', $content)) || preg_match('#\{eyou\:php([^\}]*)\}#i', $content) || preg_match('#\{php([^\}]*)\}#i', $content) || preg_match('#(\s+)language(\s*)=(\s*)("|\')?php("|\')?#i', $content)) {
112
+                return "模板里不允许有php语法,为了安全考虑,请通过FTP工具进行编辑上传。";
113
+            }
114
+            foreach ($this->disableFuns as $key => $val) {
115
+                $val_new = msubstr($val, 0, 1).'-'.msubstr($val, 1);
116
+                $content = preg_replace("/(@)?".$val."(\s*)\(/i", "{$val_new}(", $content);
117
+            }
118
+        }
119
+        $fp = fopen($file, "w");
120
+        fputs($fp, $content);
121
+        fclose($fp);
122
+        return true;
123
+    }
124
+
125
+    /**
126
+     * 上传文件
127
+     *
128
+     * @param     string  $dirname  新目录
129
+     * @param     string  $activepath  当前路径
130
+     * @param     boolean  $replace  是否替换
131
+     * @param     string  $type  文件类型:图片image , 附件file , 视频media
132
+     */
133
+    public function upload($fileElementId, $activepath = '', $replace = false, $type = 'image')
134
+    {
135
+        $retData = [];
136
+        $file = request()->file($fileElementId);
137
+        if (is_object($file) && !is_array($file)) {
138
+            $retData = $this->uploadfile($file, $activepath, $replace, $type);
139
+        } 
140
+        else if (!is_object($file) && is_array($file)) {
141
+            $fileArr = $file;
142
+            $i = 0;
143
+            $j = 0;
144
+            foreach ($fileArr as $key => $fileObj) {
145
+                if (empty($fileObj)) {
146
+                    continue;
147
+                }
148
+                $res = $this->uploadfile($fileObj, $activepath, $replace, $type);
149
+                if(!empty($res['code']) && $res['code'] == 1) {
150
+                    $i++;
151
+                } else {
152
+                    $j++;
153
+                }
154
+            }
155
+
156
+            if ($j == 0) {
157
+                $retData['code'] = 0;
158
+                $retData['msg'] = "上传失败 $i 个文件到: $activepath";
159
+            } else {
160
+                $retData['code'] = 1;
161
+                $retData['msg'] = "上传成功!";
162
+            }
163
+        }
164
+
165
+        return $retData;
166
+    }
167
+
168
+    /**
169
+     * 自定义上传
170
+     *
171
+     * @param     object  $file  文件对象
172
+     * @param     string  $activepath  当前路径
173
+     * @param     boolean  $replace  是否替换
174
+     * @param     string  $type  文件类型:图片image , 附件file , 视频media
175
+     */
176
+    public function uploadfile($file, $activepath = '', $replace = false, $type = 'image')
177
+    {
178
+        $validate = array();
179
+
180
+        /*文件类型限制*/
181
+        switch ($type) {
182
+            case 'image':
183
+                $validate_ext = tpCache('basic.image_type');
184
+                break;
185
+
186
+            case 'file':
187
+                $validate_ext = tpCache('basic.file_type');
188
+                break;
189
+
190
+            case 'media':
191
+                $validate_ext = tpCache('basic.media_type');
192
+                break;
193
+            
194
+            default:
195
+                $validate_ext = tpCache('basic.image_type');
196
+                break;
197
+        }
198
+        $validate['ext'] = explode('|', $validate_ext);
199
+        /*--end*/
200
+
201
+        /*文件大小限制*/
202
+        $validate_size = tpCache('basic.file_size');
203
+        if (!empty($validate_size)) {
204
+            $validate['size'] = $validate_size * 1024 * 1024; // 单位为b
205
+        }
206
+        /*--end*/
207
+
208
+        /*上传文件验证*/
209
+        if (!empty($validate)) {
210
+            $is_validate = $file->check($validate);
211
+            if ($is_validate === false) {
212
+                return ['code'=>0, 'msg'=>$file->getError()];
213
+            }   
214
+        }
215
+        /*--end*/
216
+
217
+        $savePath = !empty($activepath) ? trim($activepath, '/') : UPLOAD_PATH.'temp';
218
+        if (!file_exists($savePath)) {
219
+            tp_mkdir($savePath);
220
+        }
221
+
222
+        if (false == $replace) {
223
+            $fileinfo = $file->getInfo();
224
+            $filename = pathinfo($fileinfo['name'], PATHINFO_BASENAME); //获取上传文件名
225
+        } else {
226
+            $filename = $replace;
227
+        }
228
+        $fileExt = pathinfo($filename, PATHINFO_EXTENSION); //获取上传文件扩展名
229
+        if (!in_array($fileExt, $validate['ext'])) {
230
+            return ['code'=>0, 'msg'=>'上传文件后缀不允许'];
231
+        }
232
+
233
+        // 使用自定义的文件保存规则
234
+        $info = $file->move($savePath, $filename, true);
235
+        if($info){
236
+            return ['code'=>1, 'msg'=>'上传成功'];
237
+        }else{
238
+            return ['code'=>0, 'msg'=>$file->getError()];
239
+        }
240
+    }
241
+
242
+    /**
243
+     * 当前目录下的文件列表
244
+     */
245
+    public function getDirFile($directory, $activepath = '',  &$arr_file = array()) {
246
+
247
+        if (!file_exists($directory)) {
248
+            return false;
249
+        }
250
+
251
+        $fileArr = $dirArr = $parentArr = array();
252
+
253
+        $mydir = dir($directory);
254
+        while(false !== $file = $mydir->read())
255
+        {
256
+            $filesize = $filetime = $intro = '';
257
+            $filemine = 'file';
258
+
259
+            if($file != "." && $file != ".." && !is_dir("$directory/$file"))
260
+            {
261
+                @$filesize = filesize("$directory/$file");
262
+                @$filesize = format_bytes($filesize);
263
+                @$filetime = filemtime("$directory/$file");
264
+            }
265
+
266
+            if ($file == '.') 
267
+            {
268
+                continue;
269
+            } 
270
+            else if($file == "..") 
271
+            {
272
+                if($activepath == "" || $activepath == $this->maxDir) {
273
+                    continue;
274
+                }
275
+                $parentArr = array(
276
+                    array(
277
+                        'filepath'  => preg_replace("#[\/][^\/]*$#i", "", $activepath),
278
+                        'filename'  => '上级目录',
279
+                        'filesize'  => '',
280
+                        'filetime'  => '',
281
+                        'filemine'  => 'dir',
282
+                        'filetype'  => 'dir2',
283
+                        'icon'      => 'file_topdir.gif',
284
+                        'intro'  => '(当前目录:'.$activepath.')',
285
+                    ),
286
+                );
287
+                continue;
288
+            } 
289
+            else if(is_dir("$directory/$file"))
290
+            {
291
+                if(preg_match("#^_(.*)$#i", $file)) continue; #屏蔽FrontPage扩展目录和linux隐蔽目录
292
+                if(preg_match("#^\.(.*)$#i", $file)) continue;
293
+                $file_info = array(
294
+                    'filepath'  => $activepath.'/'.$file,
295
+                    'filename'  => $file,
296
+                    'filesize'  => '',
297
+                    'filetime'  => '',
298
+                    'filemine'  => 'dir',
299
+                    'filetype'  => 'dir',
300
+                    'icon'      => 'dir.gif',
301
+                    'intro'     => '',
302
+                );
303
+                array_push($dirArr, $file_info);
304
+                continue;
305
+            }
306
+            else if(preg_match("#\.(gif|png)#i",$file))
307
+            {
308
+                $filemine = 'image';
309
+                $filetype = 'gif';
310
+                $icon = 'gif.gif';
311
+            }
312
+            else if(preg_match("#\.(jpg|jpeg|bmp|webp)#i",$file))
313
+            {
314
+                $filemine = 'image';
315
+                $filetype = 'jpg';
316
+                $icon = 'jpg.gif';
317
+            }
318
+            else if(preg_match("#\.(svg)#i",$file))
319
+            {
320
+                $filemine = 'image';
321
+                $filetype = 'svg';
322
+                $icon = 'jpg.gif';
323
+            }
324
+            else if(preg_match("#\.(swf|fla|fly)#i",$file))
325
+            {
326
+                $filetype = 'flash';
327
+                $icon = 'flash.gif';
328
+            }
329
+            else if(preg_match("#\.(zip|rar|tar.gz)#i",$file))
330
+            {
331
+                $filetype = 'zip';
332
+                $icon = 'zip.gif';
333
+            }
334
+            else if(preg_match("#\.(exe)#i",$file))
335
+            {
336
+                $filetype = 'exe';
337
+                $icon = 'exe.gif';
338
+            }
339
+            else if(preg_match("#\.(mp3|wma)#i",$file))
340
+            {
341
+                $filetype = 'mp3';
342
+                $icon = 'mp3.gif';
343
+            }
344
+            else if(preg_match("#\.(wmv|api)#i",$file))
345
+            {
346
+                $filetype = 'wmv';
347
+                $icon = 'wmv.gif';
348
+            }
349
+            else if(preg_match("#\.(rm|rmvb)#i",$file))
350
+            {
351
+                $filetype = 'rm';
352
+                $icon = 'rm.gif';
353
+            }
354
+            else if(preg_match("#\.(txt|inc|pl|cgi|asp|xml|xsl|aspx|cfm)#",$file))
355
+            {
356
+                $filetype = 'txt';
357
+                $icon = 'txt.gif';
358
+            }
359
+            else if(preg_match("#\.(htm|html)#i",$file))
360
+            {
361
+                $filetype = 'htm';
362
+                $icon = 'htm.gif';
363
+            }
364
+            else if(preg_match("#\.(php)#i",$file))
365
+            {
366
+                $filetype = 'php';
367
+                $icon = 'php.gif';
368
+            }
369
+            else if(preg_match("#\.(js)#i",$file))
370
+            {
371
+                $filetype = 'js';
372
+                $icon = 'js.gif';
373
+            }
374
+            else if(preg_match("#\.(css)#i",$file))
375
+            {
376
+                $filetype = 'css';
377
+                $icon = 'css.gif';
378
+            }
379
+            else
380
+            {
381
+                $filetype = 'other';
382
+                $icon = 'other.gif';
383
+            }
384
+
385
+            $file_info = array(
386
+                'filepath'  => $activepath.'/'.$file,
387
+                'filename'  => $file,
388
+                'filesize'  => $filesize,
389
+                'filetime'  => $filetime,
390
+                'filemine'  => $filemine,
391
+                'filetype'  => $filetype,
392
+                'icon'      => $icon,
393
+                'intro'     => $intro,
394
+            );
395
+            array_push($fileArr, $file_info);
396
+        }
397
+        $mydir->close();
398
+
399
+        $arr_file = array_merge($parentArr, $dirArr, $fileArr);
400
+
401
+        return $arr_file;
402
+    }
403
+
404
+    /**
405
+     * 将冒号符反替换为反斜杠,适用于IIS服务器在URL上的双重转义限制
406
+     * @param string $filepath 相对路径
407
+     * @param string $replacement 目标字符
408
+     * @param boolean $is_back false为替换,true为还原
409
+     */
410
+    public function replace_path($activepath, $replacement = ':', $is_back = false)
411
+    {
412
+        $activepath = replace_path($activepath, $replacement, $is_back);
413
+        $activepath = preg_replace('/<(\w+)([^\>]*)>([^<]*)<\/(\w+)>/i', '', $activepath);
414
+        $activepath = preg_replace('/(<|>|;|\(|\)|\!)/i', '', $activepath);
415
+        return $activepath;
416
+    }
417
+}

+ 225
- 0
application/admin/logic/ForeignLogic.php View File

@@ -0,0 +1,225 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2018-4-3
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Db;
17
+use think\Cache;
18
+
19
+/**
20
+ * 业务逻辑
21
+ */
22
+class ForeignLogic
23
+{
24
+    public function __construct() 
25
+    {
26
+
27
+    }
28
+
29
+    /**
30
+     * 更新文档自定义文件名
31
+     * @param  [type] $aid  [description]
32
+     * @param  array  $post [description]
33
+     * @param  string $opt  [description]
34
+     * @return [type]       [description]
35
+     */
36
+    public function update_htmlfilename($aid, $post = [], $opt = 'add')
37
+    {
38
+        if ('add' == $opt) {
39
+            $seo_config = tpCache('seo');
40
+            $seo_pseudo = !empty($seo_config['seo_pseudo']) ? intval($seo_config['seo_pseudo']) : 0;
41
+            if (in_array($seo_pseudo, [2,3])) {
42
+                $seo_titleurl_format = !empty($seo_config['seo_titleurl_format']) ? intval($seo_config['seo_titleurl_format']) : 0;
43
+                if (!empty($seo_titleurl_format)) {
44
+                    $htmlfilename = $post['htmlfilename'].'_'.$aid;
45
+                    Db::name('archives')->where(['aid'=>$aid])->update(['htmlfilename'=>$htmlfilename]);
46
+                }
47
+            }
48
+        }
49
+    }
50
+
51
+    /**
52
+     * 获取标题生成外贸链接字符串
53
+     * @param  [type] $post         [description]
54
+     * @param  string $opt          [description]
55
+     * @param  array  $globalConfig [description]
56
+     * @return [type]               [description]
57
+     */
58
+    public function get_new_htmlfilename(&$htmlfilename, $post, $opt = 'add', $globalConfig = [])
59
+    {
60
+        if (empty($globalConfig)) {
61
+            $globalConfig = tpCache('global');
62
+        }
63
+        if (in_array($globalConfig['seo_pseudo'], [2,3])) {
64
+            $seo_titleurl_format = (int)$globalConfig['seo_titleurl_format'];
65
+            if (!empty($seo_titleurl_format)) {
66
+                $htmlfilename = $this->get_title_htmlfilename(trim($post['title']));
67
+                if ('edit' == $opt) {
68
+                    $htmlfilename .= '_'.$post['aid'];
69
+                }
70
+            }
71
+        }
72
+    }
73
+
74
+    /**
75
+     *  文章标题转成外贸指定格式字母串
76
+     *
77
+     * @param     string $str 字符串信息
78
+     * @param     int $ishead 是否取头字母
79
+     * @param     int $isclose 是否关闭字符串资源
80
+     * @return    string
81
+     */
82
+    public function get_title_htmlfilename($str, $ishead = 0, $isclose = 1)
83
+    {
84
+        $str = str_replace(['—'], ' ', $str);
85
+        $str = preg_replace('/(\s+)/i', ' ', $str);
86
+        try{
87
+            $s1 = iconv("UTF-8", "gb2312", $str);
88
+            $s2 = iconv("gb2312", "UTF-8", $s1);
89
+            if ($s2 == $str) {
90
+                $str = $s1;
91
+            }
92
+
93
+            static $pinyins = null;
94
+            $restr   = '';
95
+            $str     = trim($str);
96
+            $slen    = strlen($str);
97
+            if ($slen < 2) {
98
+                $str = preg_replace('/([\-\_]+)$/i', '', $str); // 去掉结尾的符号
99
+                return $str;
100
+            }
101
+            if (null === $pinyins) {
102
+                $pinyins = [];
103
+                $fp = fopen(DATA_PATH . 'conf/pinyin.dat', 'r');
104
+                while (!feof($fp)) {
105
+                    $line                         = trim(fgets($fp));
106
+                    $pinyins[$line[0] . $line[1]] = substr($line, 3, strlen($line) - 3);
107
+                }
108
+                fclose($fp);
109
+            }
110
+            for ($i = 0; $i < $slen; $i++) {
111
+                if (ord($str[$i]) > 0x80) {
112
+                    $c = $str[$i] . $str[$i + 1];
113
+                    $i++;
114
+                    if (isset($pinyins[$c])) {
115
+                        if ($ishead == 0) {
116
+                            $restr .= $pinyins[$c];
117
+                        } else {
118
+                            $restr .= $pinyins[$c][0];
119
+                        }
120
+                    // } else if ('_' == $str[$i]) {
121
+                    //     $restr .= $str[$i];
122
+                    } else {
123
+                        $restr .= "-";
124
+                    }
125
+                } else if (preg_match("/[a-z0-9]/i", $str[$i])) {
126
+                    $restr .= $str[$i];
127
+                // } else if ('_' == $str[$i]) {
128
+                //     $restr .= $str[$i];
129
+                } else {
130
+                    $restr .= "-";
131
+                }
132
+            }
133
+            if ($isclose == 0) {
134
+                unset($pinyins);
135
+            }
136
+            $restr = strtolower($restr);
137
+            $restr = preg_replace('/([\-\_]+)$/i', '', $restr); // 去掉结尾的符号
138
+            $restr = preg_replace('/([\-]+)/i', '-', $restr);
139
+            $restr = preg_replace('/([\_]+)/i', '_', $restr);
140
+            $restr = trim($restr, '-');
141
+            return $restr;
142
+        }catch (\Exception $e){
143
+            return "";
144
+        }
145
+    }
146
+
147
+    /**
148
+     * 处理更新文档的自定义文件名
149
+     * $achievepage 已完成文档数
150
+     * $batch       是否分批次执行,true:分批,false:不分批
151
+     * limit        每次执行多少条数据
152
+     */
153
+    public function handelUpdateArticle($foreign_htmlfilename_mode = 0, $achievepage = 0, $batch = true, $limit = '')
154
+    {
155
+        $msg                  = "";
156
+        $result               = $this->getArticleData($achievepage, $limit);
157
+        $info                 = $result['info'];
158
+        $data['allpagetotal'] = $pagetotal = $result['pagetotal'];
159
+        $data['achievepage']  = $achievepage;
160
+        $data['pagetotal']    = 0;
161
+
162
+        if ($batch && $pagetotal > $achievepage) {
163
+            $msg .= $msg_temp = $this->updateHtmlfilename($foreign_htmlfilename_mode, $info);
164
+            $data['achievepage'] += count($info);
165
+        }
166
+
167
+        return [$msg, $data];
168
+    }
169
+
170
+    /**
171
+     * 获取详情页数据
172
+     */
173
+    private function getArticleData($offset = 0, $limit = 0)
174
+    {
175
+        empty($limit) && $limit = 500;
176
+        $map = [];
177
+        $allow_release_channel = config('global.allow_release_channel');
178
+        $map['channel'] = ['IN', $allow_release_channel];
179
+        $map['arcrank'] = ['>=', -1];
180
+        $info = [];
181
+        $list = Db::name('archives')->field("aid,title,htmlfilename")
182
+            ->where($map)
183
+            ->order('aid asc')
184
+            ->limit($offset, $limit)
185
+            ->select();
186
+        foreach ($list as $key=>$val){
187
+            $info_value = [];
188
+            $info_value['aid'] = $val['aid'];
189
+            $info_value['title'] = trim($val['title']);
190
+            $info_value['htmlfilename'] = $val['htmlfilename'];
191
+            $info[] = $info_value;
192
+        }
193
+
194
+        // 总文档数
195
+        $pagetotal = Db::name('archives')->field('aid')->where($map)->count();
196
+
197
+        return ['info' => $info, 'pagetotal' => $pagetotal];
198
+    }
199
+
200
+    /*
201
+     * 更新文档的自定义文件名
202
+     */
203
+    private function updateHtmlfilename($foreign_htmlfilename_mode, $result)
204
+    {
205
+        $msg = "";
206
+        $globalConfig = tpCache('global');
207
+        foreach ($result as $key => $val) {
208
+            $htmlfilename = '';
209
+            if (empty($foreign_htmlfilename_mode)) {
210
+                $this->get_new_htmlfilename($htmlfilename, $val, 'edit', $globalConfig);
211
+            }
212
+            $val['htmlfilename'] = $htmlfilename;
213
+            $result[$key] = $val;
214
+        }
215
+        $archivesModel = new \app\admin\model\Archives;
216
+        $r2 = $archivesModel->saveAll($result);
217
+        if ($r2 !== false) {
218
+            
219
+        } else {
220
+            $msg .= '<span>' . '更新失败!' . $e->getMessage() . '</span><br>';
221
+        }
222
+
223
+        return $msg;
224
+    }
225
+}

+ 147
- 0
application/admin/logic/FormLogic.php View File

@@ -0,0 +1,147 @@
1
+<?php
2
+/**
3
+ * 易优CMS
4
+ * ============================================================================
5
+ * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
6
+ * 网站地址: http://www.eyoucms.com
7
+ * ----------------------------------------------------------------------------
8
+ * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
9
+ * ============================================================================
10
+ * Author: 小虎哥 <1105415366@qq.com>
11
+ * Date: 2023-3-8
12
+ */
13
+
14
+namespace app\admin\logic;
15
+
16
+use think\Model;
17
+use think\Db;
18
+
19
+class FormLogic extends Model
20
+{
21
+    public $form_db;
22
+    public $main_lang = 'cn';
23
+    public $admin_lang = 'cn';
24
+
25
+    /**
26
+     * 初始化操作
27
+     */
28
+    public function initialize() {
29
+        parent::initialize();
30
+        $this->form_db = Db::name('form');
31
+        $this->main_lang = get_main_lang();
32
+        $this->admin_lang = get_admin_lang();
33
+    }
34
+
35
+    /**
36
+     * 同步新增表单ID到多语言的模板变量里
37
+     */
38
+    public function syn_add_language_form($form_id)
39
+    {
40
+        /*单语言情况下不执行多语言代码*/
41
+        if (!is_language() || tpCache('language.language_split')) {
42
+            return true;
43
+        }
44
+        /*--end*/
45
+
46
+        $attr_group = 'form';
47
+        $languageRow = Db::name('language')->field('mark')->order('id asc')->select();
48
+        if (!empty($languageRow) && $this->admin_lang == $this->main_lang) { // 当前语言是主体语言,即语言列表最早新增的语言
49
+            $result = $this->form_db->find($form_id);
50
+            $attr_name = 'form'.$form_id;
51
+            $r = Db::name('language_attribute')->save([
52
+                'attr_title'    => $result['form_name'],
53
+                'attr_name'     => $attr_name,
54
+                'attr_group'    => $attr_group,
55
+                'add_time'      => getTime(),
56
+                'update_time'   => getTime(),
57
+            ]);
58
+            if (false !== $r) {
59
+                $data = [];
60
+                foreach ($languageRow as $key => $val) {
61
+                    /*同步新分组到其他语言分组列表*/
62
+                    if ($val['mark'] != $this->admin_lang) {
63
+                        $addsaveData = $result;
64
+                        $addsaveData['lang']  = $val['mark'];
65
+                        $addsaveData['form_name'] = $val['mark'].$addsaveData['form_name'];
66
+                        unset($addsaveData['form_id']);
67
+                        $form_id = $this->form_db->insertGetId($addsaveData);
68
+                    }
69
+                    /*--end*/
70
+                    
71
+                    /*所有语言绑定在主语言的ID容器里*/
72
+                    $data[] = [
73
+                        'attr_name' => $attr_name,
74
+                        'attr_value'    => $form_id,
75
+                        'lang'  => $val['mark'],
76
+                        'attr_group'    => $attr_group,
77
+                        'add_time'      => getTime(),
78
+                        'update_time'   => getTime(),
79
+                    ];
80
+                    /*--end*/
81
+                }
82
+                if (!empty($data)) {
83
+                    model('LanguageAttr')->saveAll($data);
84
+                }
85
+            }
86
+        }
87
+    }
88
+
89
+    /**
90
+     * 同步新增表单属性ID到多语言的模板变量里
91
+     */
92
+    public function syn_add_language_attribute($attr_id)
93
+    {
94
+        /*单语言情况下不执行多语言代码*/
95
+        if (!is_language() || tpCache('language.language_split')) {
96
+            return true;
97
+        }
98
+        /*--end*/
99
+
100
+        $attr_group  = 'form_attribute';
101
+        $languageRow = Db::name('language')->field('mark')->order('id asc')->select();
102
+        if (!empty($languageRow) && $this->admin_lang == $this->main_lang) { // 当前语言是主体语言,即语言列表最早新增的语言
103
+            $result    = Db::name('guestbook_attribute')->find($attr_id);
104
+            $attr_name = 'attr_' . $attr_id;
105
+            $r         = Db::name('language_attribute')->save([
106
+                'attr_title'  => $result['attr_name'],
107
+                'attr_name'   => $attr_name,
108
+                'attr_group'  => $attr_group,
109
+                'add_time'    => getTime(),
110
+                'update_time' => getTime(),
111
+            ]);
112
+            if (false !== $r) {
113
+                $data = [];
114
+                foreach ($languageRow as $key => $val) {
115
+                    /*同步新留言属性到其他语言留言属性列表*/
116
+                    if ($val['mark'] != $this->admin_lang) {
117
+                        $addsaveData           = $result;
118
+                        $addsaveData['lang']   = $val['mark'];
119
+                        $newTypeid             = Db::name('language_attr')->where([
120
+                            'attr_name'  => 'form' . $result['typeid'],
121
+                            'attr_group' => 'form',
122
+                            'lang'       => $val['mark'],
123
+                        ])->getField('attr_value');
124
+                        $addsaveData['typeid'] = $newTypeid;
125
+                        unset($addsaveData['attr_id']);
126
+                        $attr_id = Db::name('guestbook_attribute')->insertGetId($addsaveData);
127
+                    }
128
+                    /*--end*/
129
+
130
+                    /*所有语言绑定在主语言的ID容器里*/
131
+                    $data[] = [
132
+                        'attr_name'   => $attr_name,
133
+                        'attr_value'  => $attr_id,
134
+                        'lang'        => $val['mark'],
135
+                        'attr_group'  => $attr_group,
136
+                        'add_time'    => getTime(),
137
+                        'update_time' => getTime(),
138
+                    ];
139
+                    /*--end*/
140
+                }
141
+                if (!empty($data)) {
142
+                    model('LanguageAttr')->saveAll($data);
143
+                }
144
+            }
145
+        }
146
+    }
147
+}

+ 0
- 0
application/admin/logic/MemberLogic.php View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save