ソースを参照

Merge branch 'master' of http://git.shengws.com/zhangbj/scrm-vue

柳香萍 5 年 前
コミット
b5dc2d3257
共有41 個のファイルを変更した4086 個の追加266 個の削除を含む
  1. 2 3
      config/index.js
  2. 223 4
      package-lock.json
  3. 1 0
      package.json
  4. 34 8
      src/api/act/submitinfo.js
  5. 73 0
      src/api/activity/activity.js
  6. 9 0
      src/api/member/member.js
  7. 24 0
      src/api/mpwechat/mpmenus.js
  8. 47 0
      src/api/mpwechat/mpreply.js
  9. 15 0
      src/api/mpwechat/mpwechat.js
  10. 6 1
      src/lang/en.js
  11. 6 1
      src/lang/zh.js
  12. 5 0
      src/router/index.js
  13. 55 0
      src/router/modules/marketing_tool.js
  14. 1 1
      src/router/modules/member.js
  15. 19 0
      src/router/modules/system.js
  16. 83 14
      src/scrm_pages/article/acticleCategory.vue
  17. 92 1
      src/scrm_pages/article/commentList.vue
  18. 33 30
      src/scrm_pages/article/components/CreateArticleForm.vue
  19. 33 32
      src/scrm_pages/article/components/EditArticleForm.vue
  20. 253 127
      src/scrm_pages/article/createArticle.vue
  21. 265 0
      src/scrm_pages/marketing_tool/activity_detail.vue
  22. 23 4
      src/scrm_pages/marketing_tool/activity_list.vue
  23. 325 0
      src/scrm_pages/marketing_tool/activity_preview.vue
  24. 36 1
      src/scrm_pages/marketing_tool/activity_publish.vue
  25. 227 0
      src/scrm_pages/marketing_tool/activity_share.vue
  26. 107 0
      src/scrm_pages/marketing_tool/activity_signup_users.vue
  27. 15 3
      src/scrm_pages/marketing_tool/components/drafts_cell.vue
  28. 127 11
      src/scrm_pages/marketing_tool/components/edit_activity_edit_form.vue
  29. 2 0
      src/scrm_pages/marketing_tool/components/edit_activity_preview_form.vue
  30. 7 2
      src/scrm_pages/marketing_tool/components/published_cell.vue
  31. 8 3
      src/scrm_pages/marketing_tool/components/unapproved_cell.vue
  32. 21 1
      src/scrm_pages/members/cards.vue
  33. 77 0
      src/scrm_pages/members/components/EditCardRightForm.vue
  34. 77 10
      src/scrm_pages/weixinmp/authorization.vue
  35. 101 0
      src/scrm_pages/weixinmp/components/CreateKWReplyForm.vue
  36. 105 0
      src/scrm_pages/weixinmp/components/EditKWReplyForm.vue
  37. 30 0
      src/scrm_pages/weixinmp/components/replyNav.vue
  38. 234 0
      src/scrm_pages/weixinmp/keywordreply.vue
  39. 1159 0
      src/scrm_pages/weixinmp/menus.vue
  40. 117 0
      src/scrm_pages/weixinmp/subscribereply.vue
  41. 9 9
      src/xt_permission.js

+ 2 - 3
config/index.js ファイルの表示

@@ -17,10 +17,9 @@ module.exports = {
17 17
     // can be overwritten by process.env.HOST
18 18
     // if you want dev by ip, please set host: '0.0.0.0'
19 19
 
20
-    // host: 'jk.kuyicloud.com',
21
-
22
-
20
+    host: 'test1.sgjyun.com',
23 21
     port: 8090, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
22
+    // host: 'test1.sgjyun.com',
24 23
     autoOpenBrowser: true,
25 24
     errorOverlay: true,
26 25
     notifyOnErrors: false,

+ 223 - 4
package-lock.json ファイルの表示

@@ -1876,6 +1876,14 @@
1876 1876
         }
1877 1877
       }
1878 1878
     },
1879
+    "can-promise": {
1880
+      "version": "0.0.1",
1881
+      "resolved": "https://registry.npmjs.org/can-promise/-/can-promise-0.0.1.tgz",
1882
+      "integrity": "sha512-gzVrHyyrvgt0YpDm7pn04MQt8gjh0ZAhN4ZDyCRtGl6YnuuK6b4aiUTD7G52r9l4YNmxfTtEscb92vxtAlL6XQ==",
1883
+      "requires": {
1884
+        "window-or-global": "^1.0.1"
1885
+      }
1886
+    },
1879 1887
     "caniuse-api": {
1880 1888
       "version": "1.6.1",
1881 1889
       "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
@@ -3326,6 +3334,11 @@
3326 3334
         "randombytes": "^2.0.0"
3327 3335
       }
3328 3336
     },
3337
+    "dijkstrajs": {
3338
+      "version": "1.0.1",
3339
+      "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
3340
+      "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs="
3341
+    },
3329 3342
     "dir-glob": {
3330 3343
       "version": "2.2.2",
3331 3344
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
@@ -3537,7 +3550,6 @@
3537 3550
       "version": "1.4.1",
3538 3551
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
3539 3552
       "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
3540
-      "dev": true,
3541 3553
       "requires": {
3542 3554
         "once": "^1.4.0"
3543 3555
       }
@@ -7163,6 +7175,14 @@
7163 7175
         "pify": "^3.0.0"
7164 7176
       }
7165 7177
     },
7178
+    "map-age-cleaner": {
7179
+      "version": "0.1.3",
7180
+      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
7181
+      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
7182
+      "requires": {
7183
+        "p-defer": "^1.0.0"
7184
+      }
7185
+    },
7166 7186
     "map-cache": {
7167 7187
       "version": "0.2.2",
7168 7188
       "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
@@ -7536,6 +7556,11 @@
7536 7556
       "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
7537 7557
       "dev": true
7538 7558
     },
7559
+    "nice-try": {
7560
+      "version": "1.0.5",
7561
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
7562
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
7563
+    },
7539 7564
     "no-case": {
7540 7565
       "version": "2.3.2",
7541 7566
       "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
@@ -8003,7 +8028,6 @@
8003 8028
       "version": "1.4.0",
8004 8029
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
8005 8030
       "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
8006
-      "dev": true,
8007 8031
       "requires": {
8008 8032
         "wrappy": "1"
8009 8033
       }
@@ -8166,11 +8190,21 @@
8166 8190
         "os-tmpdir": "^1.0.0"
8167 8191
       }
8168 8192
     },
8193
+    "p-defer": {
8194
+      "version": "1.0.0",
8195
+      "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
8196
+      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
8197
+    },
8169 8198
     "p-finally": {
8170 8199
       "version": "1.0.0",
8171 8200
       "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
8172 8201
       "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
8173 8202
     },
8203
+    "p-is-promise": {
8204
+      "version": "2.1.0",
8205
+      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
8206
+      "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg=="
8207
+    },
8174 8208
     "p-limit": {
8175 8209
       "version": "1.3.0",
8176 8210
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
@@ -8444,6 +8478,11 @@
8444 8478
       "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
8445 8479
       "dev": true
8446 8480
     },
8481
+    "pngjs": {
8482
+      "version": "3.4.0",
8483
+      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
8484
+      "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
8485
+    },
8447 8486
     "portfinder": {
8448 8487
       "version": "1.0.13",
8449 8488
       "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
@@ -11226,6 +11265,182 @@
11226 11265
       "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
11227 11266
       "dev": true
11228 11267
     },
11268
+    "qrcode": {
11269
+      "version": "1.3.3",
11270
+      "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.3.3.tgz",
11271
+      "integrity": "sha512-SH7V13AcJusH3GT8bMNOGz4w0L+LjcpNOU/NiOgtBhT/5DoWeZE6D5ntMJnJ84AMkoaM4kjJJoHoh9g++8lWFg==",
11272
+      "requires": {
11273
+        "can-promise": "0.0.1",
11274
+        "dijkstrajs": "^1.0.1",
11275
+        "isarray": "^2.0.1",
11276
+        "pngjs": "^3.3.0",
11277
+        "yargs": "^12.0.5"
11278
+      },
11279
+      "dependencies": {
11280
+        "camelcase": {
11281
+          "version": "5.3.1",
11282
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
11283
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
11284
+        },
11285
+        "cross-spawn": {
11286
+          "version": "6.0.5",
11287
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
11288
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
11289
+          "requires": {
11290
+            "nice-try": "^1.0.4",
11291
+            "path-key": "^2.0.1",
11292
+            "semver": "^5.5.0",
11293
+            "shebang-command": "^1.2.0",
11294
+            "which": "^1.2.9"
11295
+          }
11296
+        },
11297
+        "execa": {
11298
+          "version": "1.0.0",
11299
+          "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
11300
+          "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
11301
+          "requires": {
11302
+            "cross-spawn": "^6.0.0",
11303
+            "get-stream": "^4.0.0",
11304
+            "is-stream": "^1.1.0",
11305
+            "npm-run-path": "^2.0.0",
11306
+            "p-finally": "^1.0.0",
11307
+            "signal-exit": "^3.0.0",
11308
+            "strip-eof": "^1.0.0"
11309
+          }
11310
+        },
11311
+        "find-up": {
11312
+          "version": "3.0.0",
11313
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
11314
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
11315
+          "requires": {
11316
+            "locate-path": "^3.0.0"
11317
+          }
11318
+        },
11319
+        "get-stream": {
11320
+          "version": "4.1.0",
11321
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
11322
+          "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
11323
+          "requires": {
11324
+            "pump": "^3.0.0"
11325
+          }
11326
+        },
11327
+        "invert-kv": {
11328
+          "version": "2.0.0",
11329
+          "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
11330
+          "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA=="
11331
+        },
11332
+        "isarray": {
11333
+          "version": "2.0.4",
11334
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz",
11335
+          "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA=="
11336
+        },
11337
+        "lcid": {
11338
+          "version": "2.0.0",
11339
+          "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
11340
+          "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
11341
+          "requires": {
11342
+            "invert-kv": "^2.0.0"
11343
+          }
11344
+        },
11345
+        "locate-path": {
11346
+          "version": "3.0.0",
11347
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
11348
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
11349
+          "requires": {
11350
+            "p-locate": "^3.0.0",
11351
+            "path-exists": "^3.0.0"
11352
+          }
11353
+        },
11354
+        "mem": {
11355
+          "version": "4.3.0",
11356
+          "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
11357
+          "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
11358
+          "requires": {
11359
+            "map-age-cleaner": "^0.1.1",
11360
+            "mimic-fn": "^2.0.0",
11361
+            "p-is-promise": "^2.0.0"
11362
+          }
11363
+        },
11364
+        "mimic-fn": {
11365
+          "version": "2.1.0",
11366
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
11367
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
11368
+        },
11369
+        "os-locale": {
11370
+          "version": "3.1.0",
11371
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
11372
+          "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
11373
+          "requires": {
11374
+            "execa": "^1.0.0",
11375
+            "lcid": "^2.0.0",
11376
+            "mem": "^4.0.0"
11377
+          }
11378
+        },
11379
+        "p-limit": {
11380
+          "version": "2.2.0",
11381
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
11382
+          "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
11383
+          "requires": {
11384
+            "p-try": "^2.0.0"
11385
+          }
11386
+        },
11387
+        "p-locate": {
11388
+          "version": "3.0.0",
11389
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
11390
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
11391
+          "requires": {
11392
+            "p-limit": "^2.0.0"
11393
+          }
11394
+        },
11395
+        "p-try": {
11396
+          "version": "2.2.0",
11397
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
11398
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
11399
+        },
11400
+        "pump": {
11401
+          "version": "3.0.0",
11402
+          "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
11403
+          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
11404
+          "requires": {
11405
+            "end-of-stream": "^1.1.0",
11406
+            "once": "^1.3.1"
11407
+          }
11408
+        },
11409
+        "semver": {
11410
+          "version": "5.7.0",
11411
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
11412
+          "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
11413
+        },
11414
+        "yargs": {
11415
+          "version": "12.0.5",
11416
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
11417
+          "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
11418
+          "requires": {
11419
+            "cliui": "^4.0.0",
11420
+            "decamelize": "^1.2.0",
11421
+            "find-up": "^3.0.0",
11422
+            "get-caller-file": "^1.0.1",
11423
+            "os-locale": "^3.0.0",
11424
+            "require-directory": "^2.1.1",
11425
+            "require-main-filename": "^1.0.1",
11426
+            "set-blocking": "^2.0.0",
11427
+            "string-width": "^2.0.0",
11428
+            "which-module": "^2.0.0",
11429
+            "y18n": "^3.2.1 || ^4.0.0",
11430
+            "yargs-parser": "^11.1.1"
11431
+          }
11432
+        },
11433
+        "yargs-parser": {
11434
+          "version": "11.1.1",
11435
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
11436
+          "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
11437
+          "requires": {
11438
+            "camelcase": "^5.0.0",
11439
+            "decamelize": "^1.2.0"
11440
+          }
11441
+        }
11442
+      }
11443
+    },
11229 11444
     "qrcodejs2": {
11230 11445
       "version": "0.0.2",
11231 11446
       "resolved": "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
@@ -14823,6 +15038,11 @@
14823 15038
         "string-width": "^1.0.2 || 2"
14824 15039
       }
14825 15040
     },
15041
+    "window-or-global": {
15042
+      "version": "1.0.1",
15043
+      "resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz",
15044
+      "integrity": "sha1-2+RboqKRqrxW1iz2bEW3+jIpRt4="
15045
+    },
14826 15046
     "window-size": {
14827 15047
       "version": "0.1.0",
14828 15048
       "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
@@ -14889,8 +15109,7 @@
14889 15109
     "wrappy": {
14890 15110
       "version": "1.0.2",
14891 15111
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
14892
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
14893
-      "dev": true
15112
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
14894 15113
     },
14895 15114
     "write": {
14896 15115
       "version": "0.2.1",

+ 1 - 0
package.json ファイルの表示

@@ -54,6 +54,7 @@
54 54
     "normalize.css": "7.0.0",
55 55
     "nprogress": "0.2.0",
56 56
     "print-js": "^1.0.50",
57
+    "qrcode": "^1.3.3",
57 58
     "qrcodejs2": "0.0.2",
58 59
     "screenfull": "4.2.0",
59 60
     "serve-static": "1.13.2",

+ 34 - 8
src/api/act/submitinfo.js ファイルの表示

@@ -1,11 +1,11 @@
1 1
 import request from '@/utils/request'
2 2
 
3
-export function submitForm (params){
4
-    //console.log("文章列表",params)
3
+export function submitForm (data){
4
+    console.log("文章列表",data)
5 5
     return request({
6 6
         url: '/api/acticle/createacticle',
7
-        method: 'Get',
8
-        params: params
7
+        method: 'Post',
8
+        data: data
9 9
     })
10 10
 }
11 11
 
@@ -43,10 +43,36 @@ export function GetCategorys(params){
43 43
      })
44 44
 }
45 45
 
46
-export function EditArticleCategory(MenuId,data){
46
+export function EditArticleCategory(id,data){
47
+    console.log("abc",data)
47 48
     return request({
48
-        url:'/api/acticle/edit?MenuId='+MenuId,
49
-        method:'put',
50
-        data,data
49
+        url:'/api/acticle/edit?id='+id,
50
+        method:'Post',
51
+        data:data
52
+    })
53
+}
54
+
55
+export function DeleteCategorys(data){
56
+     return request({
57
+         url:'/api/acticle/delete',
58
+         method:'delete',
59
+         data:data
60
+     })
61
+}
62
+
63
+export function addVido(data){
64
+    console.log("发布视频",data)
65
+    return request({
66
+        url:"/api/acticle/addvido",
67
+        method:"post",
68
+        data:data,
69
+    })
70
+}
71
+
72
+export function Savedraft(data){
73
+    return request({
74
+        url:"/api/acticle/savedraft",
75
+        method:"post",
76
+        data:data,
51 77
     })
52 78
 }

+ 73 - 0
src/api/activity/activity.js ファイルの表示

@@ -11,4 +11,77 @@ export function fetchActivities(page, keyword, status) {
11 11
     method: 'get',
12 12
     params: params,
13 13
   })
14
+}
15
+
16
+export function fetchActivity(id) {
17
+  return request({
18
+    url: "/api/activity",
19
+    method: "get",
20
+    params: {
21
+      id: id,
22
+    }
23
+  })
24
+}
25
+
26
+export function submitActivity(publish, activity) {
27
+  return request({
28
+    url: "/api/activity/submit",
29
+    method: "post",
30
+    params: {
31
+      publish: publish,
32
+    },
33
+    data: activity,
34
+  })
35
+}
36
+
37
+export function fetchActivityDetailViewData(id) {
38
+  return request({
39
+    url: "/api/activity/detailview",
40
+    method: "get",
41
+    params: {
42
+      id: id,
43
+    }
44
+  })
45
+}
46
+
47
+export function fetchActivitySignupUsers(activity_id, keyword, page) {
48
+  return request({
49
+    url: "/api/activity/signups",
50
+    method: "get",
51
+    params: {
52
+      id: activity_id,
53
+      keyword: keyword,
54
+      page: page,
55
+    }
56
+  })
57
+}
58
+
59
+export function deleteActivity(activity_id) {
60
+  return request({
61
+    url: "/api/activity/delete",
62
+    method: "post",
63
+    params: {
64
+      id: activity_id,
65
+    }
66
+  })
67
+}
68
+
69
+export function publishActivity(activity_id) {
70
+  return request({
71
+    url: "/api/activity/publish",
72
+    method: "post",
73
+    params: {
74
+      id: activity_id,
75
+    }
76
+  })
77
+}
78
+
79
+export function getActivityShareInfo(activity_id) {
80
+  return request({
81
+    url: "/api/activity/shareinfo",
82
+    method: "get",
83
+    params: {
84
+      id: activity_id,
85
+    }
86
+  })
14 87
 }

+ 9 - 0
src/api/member/member.js ファイルの表示

@@ -118,3 +118,12 @@ export function DeleteMemberShipCard(data) {
118 118
     data: data
119 119
   })
120 120
 }
121
+
122
+
123
+export function EditRight(data) {
124
+  return request({
125
+    url: '/api/membercard/right/edit',
126
+    method: 'put',
127
+    data: data
128
+  })
129
+}

+ 24 - 0
src/api/mpwechat/mpmenus.js ファイルの表示

@@ -0,0 +1,24 @@
1
+import request from '@/utils/request'
2
+
3
+export function GetMenus() {
4
+  return request({
5
+    url: '/api/mpwechat/menus',
6
+    method: 'get',
7
+  })
8
+}
9
+
10
+export function SaveMenus(data) {
11
+  return request({
12
+    url: '/api/mpwechat/savemenus',
13
+    method: 'put',
14
+    data:data,
15
+  })
16
+}
17
+
18
+export function DeleteMenu(data) {
19
+  return request({
20
+    url: '/api/mpwechat/deletemenus',
21
+    method: 'post',
22
+    data:data,
23
+  })
24
+}

+ 47 - 0
src/api/mpwechat/mpreply.js ファイルの表示

@@ -0,0 +1,47 @@
1
+import request from '@/utils/request'
2
+
3
+export function GetSubscribeRplay() {
4
+    return request({
5
+        url: '/api/mpwechat/reply/subscribe',
6
+        method: 'get',
7
+    })
8
+}
9
+
10
+export function SaveSubscribeRplay(data) {
11
+    return request({
12
+        url: '/api/mpwechat/reply/subscribe',
13
+        method: 'put',
14
+        data:data,
15
+    })
16
+}
17
+    
18
+export function GetKeyWordReplys(params) {
19
+    return request({
20
+        url: '/api/mpwechat/reply/kewords',
21
+        method: 'get',
22
+        params:params,
23
+    })
24
+}
25
+
26
+export function CreateKeyWordReply(data) {
27
+    return request({
28
+        url: '/api/mpwechat/reply/keword',
29
+        method: 'post',
30
+        data:data,
31
+    })
32
+}
33
+export function EditKeyWordReply(id,data) {
34
+    return request({
35
+        url: '/api/mpwechat/reply/keword?id='+id,
36
+        method: 'put',
37
+        data:data,
38
+    })
39
+}
40
+
41
+export function DeleteReplys(data) {
42
+    return request({
43
+        url: '/api/mpwechat/replys',
44
+        method: 'delete',
45
+        data:data,
46
+    })
47
+}

+ 15 - 0
src/api/mpwechat/mpwechat.js ファイルの表示

@@ -0,0 +1,15 @@
1
+import request from '@/utils/request'
2
+
3
+export function GetAuthorizationInfo() {
4
+  return request({
5
+    url: '/api/mpwechat/authorization',
6
+    method: 'get',
7
+  })
8
+}
9
+
10
+export function GetAuthUrl() {
11
+  return request({
12
+    url: '/api/mpwechat/authurl',
13
+    method: 'get',
14
+  })
15
+}

+ 6 - 1
src/lang/en.js ファイルの表示

@@ -114,7 +114,12 @@ export default {
114 114
     marketingTool: "marketing tools",
115 115
     activityList: "activity list",
116 116
     activityPublish: "publish activity",
117
-    systemsetting:'Systemsetting'
117
+    activityModify: "edit activity",
118
+    systemsetting:'Systemsetting',
119
+    activityDetail: "activity detail",
120
+    activityShare: "activity share",
121
+    activityPreview: "activity preview",
122
+    activitySignupList: "activity sign up list",
118 123
   },
119 124
   navbar: {
120 125
     logOut: 'Log Out',

+ 6 - 1
src/lang/zh.js ファイルの表示

@@ -162,8 +162,13 @@ export default {
162 162
     marketingTool: "营销工具",
163 163
     activityList: "活动列表",
164 164
     activityPublish: "发布活动",
165
+    activityModify: "编辑活动",
165 166
     systemsetting:'系统设置',
166
-    staffmanagement:'员工管理'
167
+    staffmanagement:'员工管理',
168
+    activityDetail: "活动详情",
169
+    activityShare: "活动分享",
170
+    activityPreview: "活动预览",
171
+    activitySignupList: "报名列表",
167 172
   },
168 173
   navbar: {
169 174
     logOut: '退出登录',

+ 5 - 0
src/router/index.js ファイルの表示

@@ -68,6 +68,11 @@ var _constant_router_map = [{
68 68
       noCache: true
69 69
     }
70 70
   }]
71
+},
72
+{
73
+  path: '/activity/preview',
74
+  component: () => import('@/scrm_pages/marketing_tool/activity_preview'),
75
+  hidden: true
71 76
 }
72 77
   // service
73 78
 ]

+ 55 - 0
src/router/modules/marketing_tool.js ファイルの表示

@@ -28,5 +28,60 @@ export default {
28 28
         noCache: true
29 29
       }
30 30
     },
31
+    {
32
+      path: '/activity/modify',
33
+      hidden: true,
34
+      is_menu: false,
35
+      component: () => import('@/scrm_pages/marketing_tool/activity_publish'),
36
+      name: 'activityModify',
37
+      meta: {
38
+        title: 'activityModify',
39
+        noCache: true
40
+      }
41
+    },
42
+    {
43
+      path: "/activity",
44
+      hidden: true,
45
+      is_menu: false,
46
+      component: () => import("@/scrm_pages/marketing_tool/activity_detail"),
47
+      name: "activityDetail",
48
+      meta: {
49
+        title: "activityDetail",
50
+        noCache: true,
51
+      }
52
+    },
53
+    {
54
+      path: "/activity/share",
55
+      hidden: true,
56
+      is_menu: false,
57
+      component: () => import("@/scrm_pages/marketing_tool/activity_share"),
58
+      name: "activityShare",
59
+      meta: {
60
+        title: "activityShare",
61
+        noCache: true,
62
+      }
63
+    },
64
+    // {
65
+    //   path: "/activity/preview",
66
+    //   hidden: true,
67
+    //   is_menu: false,
68
+    //   component: () => import("@/scrm_pages/marketing_tool/activity_preview"),
69
+    //   name: "activityPreview",
70
+    //   meta: {
71
+    //     title: "activityPreview",
72
+    //     noCache: true,
73
+    //   }
74
+    // },
75
+    {
76
+      path: "/activity/signupusers",
77
+      hidden: true,
78
+      is_menu: false,
79
+      component: () => import("@/scrm_pages/marketing_tool/activity_signup_users"),
80
+      name: "activitySignupList",
81
+      meta: {
82
+        title: "activitySignupList",
83
+        noCache: true,
84
+      }
85
+    },
31 86
   ]
32 87
 }

+ 1 - 1
src/router/modules/member.js ファイルの表示

@@ -15,7 +15,7 @@ export default {
15 15
     {
16 16
       path: '/member/members',
17 17
       component: () => import('@/scrm_pages/members/members'),
18
-      name: 'memberslist',
18
+      name: 'memberslists',
19 19
       meta: { title: '会员管理', noCache: true }
20 20
     },
21 21
     {

+ 19 - 0
src/router/modules/system.js ファイルの表示

@@ -17,6 +17,25 @@ export default {
17 17
       name: 'weixinMpAuth',
18 18
       meta: { title: '公众号授权', noCache: true }
19 19
     },
20
+    {
21
+      path: '/weixinmp/menus',
22
+      component: () => import('@/scrm_pages/weixinmp/menus'),
23
+      name: 'weixinMpMenus',
24
+      meta: { title: '公众号菜单', noCache: true }
25
+    },
26
+    {
27
+      path: '/weixinmp/reply/subscribe',
28
+      component: () => import('@/scrm_pages/weixinmp/subscribereply'),
29
+      name: 'weixinAutoReply',
30
+      meta: { title: '自动回复', noCache: true }
31
+    },
32
+    {
33
+      path: '/weixinmp/reply/keyword',
34
+      component: () => import('@/scrm_pages/weixinmp/keywordreply'),
35
+      name: 'weixinKeywordReply',
36
+      hidden: true,
37
+      meta: { title: '关键词回复', noCache: true }
38
+    },
20 39
     {
21 40
       path: '/Systemsetting/staffmanagement',
22 41
       component: () => import('@/scrm_pages/Systemsetting/staffmanagement'),

+ 83 - 14
src/scrm_pages/article/acticleCategory.vue ファイルの表示

@@ -6,8 +6,8 @@
6 6
       </div>
7 7
       <div class="app-container">
8 8
         <div class="filter-container" style="margin-top: 10px;margin-left: 5px">
9
-          <el-checkbox style="width: 30px">全选</el-checkbox>
10
-          <el-button size="small" icon="el-icon-delete">批量删除</el-button>
9
+          <el-checkbox style="width: 30px" @change="changeCheck" v-model="checkAllStatus">全选</el-checkbox>
10
+          <el-button size="small" icon="el-icon-delete" @click="openDeleteCategorys">批量删除</el-button>
11 11
 
12 12
         </div>
13 13
 
@@ -18,6 +18,7 @@
18 18
             ref="multipleTable"
19 19
             :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}"
20 20
             :data="articsData"
21
+            @selection-change="handleSelectionChange"
21 22
           >
22 23
             <el-table-column
23 24
               type="selection"
@@ -26,7 +27,7 @@
26 27
 
27 28
             <el-table-column label="分类名称" align="center">
28 29
               <template slot-scope="scope">
29
-                {{scope.row.Name}}
30
+                {{scope.row.name}}
30 31
               </template>
31 32
             </el-table-column>
32 33
 
@@ -38,7 +39,7 @@
38 39
 
39 40
             <el-table-column label="分类排序" align="center">
40 41
               <template slot-scope="scope">
41
-                {{scope.row.Order}}
42
+                {{scope.row.order}}
42 43
               </template>
43 44
             </el-table-column>
44 45
 
@@ -58,7 +59,7 @@
58 59
                     size="mini"
59 60
                     type="danger"
60 61
                     icon="el-icon-delete"
61
-                    @click="handleDelete(scope.$index, scope.row)">
62
+                    @click="openDelete(scope.row,scope.$index)">
62 63
                   </el-button>
63 64
                 </el-tooltip>
64 65
 
@@ -92,7 +93,7 @@
92 93
   import BreadCrumb from '../components/bread-crumb'
93 94
   import CreateArticleForm from "./components/CreateArticleForm";
94 95
   import EditArticleForm from "./components/EditArticleForm";
95
-  import { GetCategorys } from '@/api/act/submitinfo'
96
+  import { GetCategorys,DeleteCategorys } from '@/api/act/submitinfo';
96 97
   export default {
97 98
     name: 'acticleCategory',
98 99
     components:{
@@ -108,20 +109,21 @@
108 109
         ],
109 110
         articsData:[],
110 111
         articData:{
111
-          Name:'',
112
-          Summary:'',
113
-          Order:'',
114
-          MenuId:0,
112
+          name:'',
113
+          summary:'',
114
+          order:'',
115
+          id:0,
115 116
         },
116 117
         total:0,
117 118
         listQuery:{
118 119
           page:1,
119 120
           limit:10,
120 121
           name:'',
121
-          content:'',
122
-          sort:'',
122
+          summary:'',
123
+          order:'',
123 124
         },
124
-         artilceIndex:-1,
125
+         artilceIndex:0,
126
+         checkAllStatus:false,
125 127
       }
126 128
     },
127 129
 
@@ -157,7 +159,74 @@
157 159
             console.log("heh",this.articsData)  
158 160
              this.artilceIndex = index 
159 161
              this.$refs.editArticleForm.open();        
160
-        }
162
+        },
163
+          changeCheck(){
164
+          this.$refs.multipleTable.clearSelection();
165
+          if (this.checkAllStatus) {
166
+            this.$refs.multipleTable.toggleAllSelection();
167
+            }
168
+           },
169
+        openDelete(row,index){
170
+          this.$confirm('确认要删除该分类名称吗?<br>删除后,该分类名称信息将无法恢复',{
171
+             dangerouslyUseHTMLString:true,
172
+             confirmButtonText: '确定',
173
+             cancelButtonText: '取消',
174
+             type: 'warning'   
175
+          }).then(()=>{
176
+            var ids = [];
177
+            ids.push(row.id);
178
+            DeleteCategorys({ids:ids}).then(response=>{
179
+                var res = response.data;
180
+                if(res.state === 1){
181
+                    this.articsData.splice(index,1);
182
+                    this.$message.success("删除会员成功");
183
+                }else{
184
+                   this.$message.error(res.msg);
185
+                }
186
+            }).catch(e=>{});
187
+          }).catch(() => {
188
+            return false        
189
+          });
190
+        },
191
+          handleSelectionChange(val){
192
+          this.selectedMembers = val;
193
+        },
194
+        openDeleteCategorys(){
195
+            if (this.selectedMembers.length==0) {
196
+            this.$message.error("请选择要删除的会员");
197
+            return false;
198
+          }   
199
+
200
+          this.$confirm('确认要删除所选的分类名称吗?<br>删除后,分类名称信息将无法恢复', '删除提示',{
201
+             dangerouslyUseHTMLString:true,
202
+             confirmButtonText: '确定',
203
+             cancelButtonText: '取消',
204
+             type: 'warning'
205
+          }).then(()=>{
206
+              var ids = [];
207
+              var idMap = {};
208
+              for (const index in this.selectedMembers) {
209
+                ids.push(this.selectedMembers[index].id);
210
+                idMap[this.selectedMembers[index].id] = this.selectedMembers[index].id;
211
+            }
212
+            DeleteCategorys({ids:ids}).then(response=>{
213
+               var res = response.data;
214
+               if(res.state ===1){
215
+                 var articsDatalength = this.articsData.length;
216
+                  for (let index = articsDatalength-1; index >= 0; index--) {
217
+                  if(this.articsData[index].id in idMap) {
218
+                    this.articsData.splice(index, 1);
219
+                  }                  
220
+                }
221
+                 this.$message.success("删除会员成功");
222
+               }else{
223
+                 this.$message.error(res.msg);
224
+              }
225
+            }).catch(e=>{});
226
+          }).catch(() => {
227
+            return false        
228
+          });
229
+        },
161 230
     },
162 231
      created(){
163 232
          this.GetCategorys()

+ 92 - 1
src/scrm_pages/article/commentList.vue ファイルの表示

@@ -4,7 +4,23 @@
4 4
           <bread-crumb :crumbs='crumbs'></bread-crumb>
5 5
         </div>
6 6
         <div class="app-container">
7
-         评论列表
7
+           评论列表
8
+           <el-form-item ref="videocontentvideo" style="display:none;">
9
+              <img :src="imgurl">
10
+              <video width="320" height="240" controls id="upvideo">
11
+              </video>
12
+              <img :src="modlevidel" />
13
+            </el-form-item>
14
+
15
+            <el-form-item class="upload-demo-content" v-show="formLabelAlign.type==2">
16
+            <el-upload class="upload-demo" :limit="1" :on-exceed="exceedhandle" drag :file-list="filsListArray" :action="configuploadurl" :on-success="successuploadhandle" accept="video" name="fileList" :before-upload="beforeUploadVideo">
17
+              <i class="el-icon-upload"></i>
18
+              <div class="el-upload__text">将视频文件拖到此处,或
19
+                <em>点击上传</em>
20
+              </div>
21
+              <div class="el-upload__tip" slot="tip"></div>
22
+            </el-upload>
23
+          </el-form-item>
8 24
         </div>
9 25
     </div>
10 26
 </template>
@@ -22,7 +38,82 @@
22 38
           { path: false, name: '文章管理' },
23 39
           { path: '/articles/commentList', name: '评论列表' }
24 40
         ],
41
+        imgurl:'',
42
+        modlevidel:'',
43
+        formLabelAlign:'',
44
+        modlevidel:'',
45
+        filsListArray:[],
46
+        elForm:'',
47
+        configuploadurl:'',
48
+      }
49
+    },
50
+    methods:{
51
+      successuploadhandle(response, file, fileList) {
52
+      this.formLabelAlign.video = this.modlevidel =
53
+        response.data.fileList[0].url;
54
+        this.filsListArray = [];
55
+        this.filsListArray.push({
56
+        name: this.formLabelAlign.video,
57
+        url: this.formLabelAlign.video
58
+       });
59
+        this.findvideocover();
60
+    },
61
+      exceedhandle(files, fileList) {
62
+      this.$message.error("只能上传一个视频额");
63
+      },
64
+      beforeUploadVideo(file) {
65
+      if (
66
+        [
67
+          "video/mp4",
68
+          "video/ogg",
69
+          "video/flv",
70
+          "video/avi",
71
+          "video/wmv",
72
+          "video/rmvb"
73
+        ].indexOf(file.type) == -1
74
+      ) {
75
+        this.$message.error("请上传正确的视频格式");
76
+        return false;
25 77
       }
78
+     },
79
+
80
+     findvideocover() {
81
+      let _this = this;
82
+      this.$nextTick(() => {
83
+        let video = document.getElementById("upvideo");
84
+        let source = document.createElement("source");
85
+        // source.src = require("../../assets/5b086751dbb7af1ea8fa8d05e66fe5c3.mp4");this.formLabelAlign.video
86
+        source.src = this.formLabelAlign.video;
87
+        source.type = "video/mp4";
88
+        video.appendChild(source);
89
+        video.addEventListener("loadeddata", function() {
90
+          var canvas = document.createElement("canvas");
91
+          canvas.width = "320";
92
+          canvas.height = "320";
93
+          canvas
94
+            .getContext("2d")
95
+            .drawImage(video, 0, 0, canvas.width, canvas.width);
96
+          var img = document.createElement("img");
97
+          let imgsrc = canvas.toDataURL("image/png");
98
+          _this.Videoframehandle(imgsrc.split(",")[1]);
99
+        });
100
+      });
101
+      },
102
+
103
+      showvideohandle() {
104
+       this.$alert(
105
+        `<video width="320" height="240" controls>
106
+                      <source src="${
107
+                        this.filsListArray[0].url
108
+                      }"  type="video/mp4">
109
+                      您的浏览器不支持 HTML5 video 标签。
110
+                    </video>`,
111
+        "视频预览",
112
+        {
113
+          dangerouslyUseHTMLString: true
114
+        }
115
+      );
116
+    },
26 117
     }
27 118
   }
28 119
 </script>

+ 33 - 30
src/scrm_pages/article/components/CreateArticleForm.vue ファイルの表示

@@ -1,5 +1,4 @@
1 1
 <template>
2
-
3 2
     <div id="create-article-form-box">
4 3
       <el-dialog
5 4
         title="添加分类"
@@ -15,18 +14,18 @@
15 14
             </el-form-item>
16 15
           </el-row>
17 16
           <el-row :span=20>
18
-            <el-form-item label="分类描述:" required prop="content">
19
-              <keep-alive>
20
-                <neditor ref="neditor"
21
-                         id="editor"
22
-                         v-bind:r_content="form.content">
23
-                </neditor>
24
-              </keep-alive>
17
+            <el-form-item label="分类描述:" required prop="summary">      
18
+                <div style="margin: 10px 0;"></div>
19
+                <el-input
20
+                 type="textarea"
21
+                :autosize="{ minRows: 2, maxRows: 4}"
22
+                 v-model="form.summary">
23
+                </el-input>
25 24
             </el-form-item>
26 25
           </el-row>
27 26
           <el-row :span=20>
28
-            <el-form-item label="排序" required prop="sort">
29
-              <el-input v-model="form.sort">
27
+            <el-form-item label="排序:" required prop="order">
28
+              <el-input v-model="form.order">
30 29
 
31 30
               </el-input>
32 31
             </el-form-item>
@@ -42,27 +41,31 @@
42 41
 </template>
43 42
 
44 43
 <script>
45
-    import Neditor from '@/components/Neditor'
46 44
     import { addCategory } from '@/api/act/submitinfo'
47 45
     export default {
48
-        name: "CreateArticleForm",
49
-         components:{
50
-           Neditor,
51
-        },
46
+        name: "CreateArticleForm",       
47
+           props:{
48
+             articsData:{
49
+             type: Array,
50
+             default: function () {
51
+             return [];
52
+        }
53
+      }
54
+           },
52 55
             data(){
53 56
                 return {
54 57
                     centerDialogVisible:false,
55 58
                     rules: {
56 59
                     name: [{required: true, message: "请填写分类名称",},],
57
-                    content: [{required: true,message:"请填写分类描述"}],
58
-                    sort: [{required: true,message:"请填写排序"}]
59
-                },
60
-                 form:{
61
-                   name:"",
62
-                   content:"",
63
-                   sort:"",
64
-                },
60
+                    summary: [{required: true,message:"请填写分类描述"}],
61
+                    order: [{required: true,message:"请填写排序"}]
62
+                 },
65 63
                 acticleform:[],
64
+                 form:{
65
+                    name:"",
66
+                    summary:"",
67
+                    order:"",
68
+                   },
66 69
              }
67 70
           },   
68 71
            methods:{
@@ -74,18 +77,18 @@
74 77
                      this.$refs[formName].resetFields();
75 78
                    }
76 79
                   },
77
-               addCategory(formName){
78
-                  this.form.content = this.$refs.neditor.content
80
+               addCategory(formName){                 
79 81
                    this.$refs[formName].validate((valid)=>{
80
-                       if(valid){
82
+                       if(valid){                         
81 83
                             addCategory(this.form).then(response =>{
82
-                                  console.log(response.data.state)
84
+                                  console.log("添加分类响应",response.data.state)
83 85
                                   if(response.data.state==1){
84 86
                                     var category = response.data.data.category
85
-                                    this.centerDialogVisible=false
87
+                                    console.log("category是什么",category)
88
+                                    this.centerDialogVisible=false;
89
+                                    this.articsData.unshift(category);
86 90
                                     this.resetForm("acticleform");
87
-                                    this.$message.success("添加分类成功");
88
-                                    console.log("coo",category)
91
+                                    this.$message.success("添加分类成功");                           
89 92
                                   }
90 93
                             });
91 94
                        }   

+ 33 - 32
src/scrm_pages/article/components/EditArticleForm.vue ファイルの表示

@@ -7,47 +7,46 @@
7 7
         center>
8 8
         <el-form label-width="90px" class="clearfix" :model="form" ref="acticleform" :rules="rules">
9 9
           <el-row :span=20>
10
-            <el-form-item label="分类名称:" required prop="Name">
11
-              <el-input v-model="form.Name"></el-input>
10
+            <el-form-item label="分类名称:" required prop="name">
11
+              <el-input v-model="form.name"></el-input>
12 12
             </el-form-item>
13 13
           </el-row>
14 14
           <el-row :span=20>
15
-            <el-form-item label="分类描述:" required prop="Summary">
16
-              <keep-alive>
17
-                <neditor ref="neditor"
18
-                         id="editor"
19
-                         v-bind:r_content="form.Summary">
20
-                </neditor>
21
-              </keep-alive>
15
+            <el-form-item label="分类描述:" required prop="summary">
16
+              <div style="margin: 10px 0;"></div>
17
+              <el-input
18
+                 type="textarea"
19
+                :autosize="{minRows: 2, maxRows: 4}"
20
+                 v-model="form.summary">
21
+                </el-input>
22 22
             </el-form-item>
23 23
           </el-row>
24 24
           <el-row :span=20>
25
-            <el-form-item label="排序" required prop="Order">
26
-              <el-input v-model="form.Order"></el-input>
25
+            <el-form-item label="排序" required prop="order">
26
+              <el-input v-model="form.order"></el-input>
27 27
             </el-form-item>
28 28
           </el-row>
29 29
         </el-form>
30 30
         <span slot="footer" class="dialog-footer">
31
-               <el-button type="primary" @click="submitForm('acticleform')">保存</el-button>
31
+               <el-button 
32
+               type="primary" 
33
+               @click="submitForm('acticleform')">保存
34
+               </el-button>
32 35
               <el-button  @click="centerDialogVisible = false">取消</el-button>
33 36
              </span>
34 37
       </el-dialog>   
35 38
     </div>
36 39
 </template>
37 40
 <script>
38
-import Neditor from '@/components/Neditor'
39 41
  import { EditArticleCategory } from '@/api/act/submitinfo'
40 42
 export default {
41 43
     name: "EditArticleForm",
42
-     components:{
43
-        Neditor,
44
-      },
45 44
       props:{
46 45
         form:{
47
-           Name:'',
48
-          Summary:'',
49
-          Order:'',
50
-          MenuId:0,
46
+           name:'',
47
+           summary:'',
48
+           order:'',
49
+           id:0,
51 50
         },
52 51
       artilceIndex:{
53 52
           type:Number,
@@ -64,9 +63,9 @@ export default {
64 63
           return {
65 64
           centerDialogVisible:false,
66 65
            rules: {
67
-             Name: [{required: true, message: "请填写分类名称",},],
68
-             Summary: [{required: true,message:"请填写分类描述"}],
69
-             Order: [{required: true,message:"请填写排序"}]
66
+             name: [{required: true, message: "请填写分类名称",},],
67
+             summary: [{required: true,message:"请填写分类描述"}],
68
+             order: [{required: true,message:"请填写排序"}]
70 69
               },
71 70
              }
72 71
           }, 
@@ -80,20 +79,22 @@ export default {
80 79
                    }
81 80
                 },  
82 81
               submitForm(forname){ 
83
-                alert("aaa")
84 82
                 this.$refs[forname].validate((valid)=>{
85 83
                    if(valid){
86
-                      EditArticleCategory(this.form.MenuId,this.form).then(response=>{
87
-                            console.log("id是谁",this.form.MenuId)
88
-                            console.log(this.form)
84
+                       var order = this.form.order
85
+                       var ord = parseInt(order)
86
+                       this.form.order = ord
87
+                      EditArticleCategory(this.form.id,this.form).then(response=>{                        
89 88
                            var res =  response.data;
90
-                           console.log(res.state)
89
+                           console.log("返回响应",res.state)
91 90
                            if(res.state ===1 ){
92
-                              var categorys = res.data.categorys; 
91
+                              var categorys = res.data.category; 
93 92
                               console.log("categorys是什么",categorys)
94
-                              this.articsData[this.artilceIndex].name = categorys.Name;
95
-                              this.articsData[this.artilceIndex].content = categorys.Summary;
96
-                              this.articsData[this.artilceIndex].sort = categorys.Order;
93
+                              this.articsData[this.artilceIndex].name = categorys.name;
94
+                              this.articsData[this.artilceIndex].summary = categorys.summary;
95
+                              this.articsData[this.artilceIndex].order = categorys.order;
96
+                              //this.articsData.unshift(categorys);
97
+                              // this.resetForm("acticleform");
97 98
                               this.centerDialogVisible = false;
98 99
                               this.$message.success("编辑文章分类成功");
99 100
                            }

+ 253 - 127
src/scrm_pages/article/createArticle.vue ファイルの表示

@@ -7,13 +7,13 @@
7 7
     <div class="app-container">
8 8
     <el-tabs type="border-card">
9 9
       <el-tab-pane label="文章">
10
-        <el-form label-width="80px" class="clearfix" :model="form" ref="form"  :element-loading-text="loadingText">
10
+        <el-form label-width="100px" class="clearfix" :model="form" ref="arctileform"  :element-loading-text="loadingText" :rules="artilcrules">
11 11
           <el-row>
12 12
             <el-col :span="23">
13
-                <el-form-item label="文章标题:">
14
-                    <el-input v-model="form.act_name"  placeholder="文章标题"></el-input>
13
+                <el-form-item label="文章标题:" required prop="act_name">
14
+                    <el-input v-model="form.act_name"></el-input>
15 15
                 </el-form-item>
16
-              <el-form-item label="文章内容:">
16
+              <el-form-item label="文章内容:" required prop="act_content">
17 17
                 <keep-alive>
18 18
                   <neditor ref="neditor"
19 19
                            id="editor"
@@ -25,7 +25,7 @@
25 25
                   <el-radio v-model="radio" label="1" @click.native.prevent="select()" >单图</el-radio>
26 26
                   <el-radio v-model="radio" label="2" @click.native.prevent="clickitem()" >三图</el-radio>
27 27
               </el-form-item>
28
-              <el-form-item prop="org_log">
28
+              <el-form-item>
29 29
                 <el-col :span="3">
30 30
                   <div>
31 31
                     <el-upload
@@ -38,7 +38,7 @@
38 38
                       :on-error="handleAvatarError"
39 39
                       :on-success="handleAvatarSuccess"
40 40
                       :before-upload="beforeAvatarUpload">
41
-                      <img v-if="imageUrl" :src="imageUrl" class="avatar">
41
+                      <img v-if="form.org_logo" :src="form.org_logo" class="avatar">
42 42
                       <i v-else class="el-icon-plus avatar-uploader-icon"></i>
43 43
                     </el-upload>
44 44
                   </div>
@@ -46,7 +46,7 @@
46 46
                 <el-col :span="3">
47 47
                   <div v-if="show">
48 48
                     <el-upload
49
-                      v-loading="guploading"
49
+                      v-loading="uploading"
50 50
                       :element-loading-text="loadingText"
51 51
                       class="avatar-uploader"
52 52
                       :data="uploadData"
@@ -78,13 +78,13 @@
78 78
                   </div>
79 79
                 </el-col>
80 80
               </el-form-item>
81
-               <el-form-item label="所属分类:">
81
+               <el-form-item label="所属分类:" prop="act_type">
82 82
                  <el-select v-model="form.act_type" placeholder="请先选择文章所属分类"  @change="changeActtype()">
83 83
                    <el-option
84 84
                      v-for="item in options"
85
-                     :key="item.MenuId"
86
-                     :label="item.Name"
87
-                     :value="item.MenuId">
85
+                     :key="item.id"
86
+                     :label="item.name"
87
+                     :value="item.id">
88 88
                    </el-option>
89 89
                  </el-select>
90 90
                </el-form-item>
@@ -94,8 +94,8 @@
94 94
           <el-row :span="24">
95 95
             <el-col :span="24">
96 96
                 <el-form-item>
97
-                      <el-button size="small" type="primary" style="width: 100px"  @click="submitForm();centerDialogVisible = true">发布</el-button>
98
-                      <el-button size="small" style="width: 100px">预览</el-button>
97
+                      <el-button size="small" type="primary" style="width: 100px"  @click="submitForm('arctileform');centerDialogVisible=false">发布</el-button>
98
+                      <el-button size="small" style="width: 100px" @click="preview('arctileform')">预览</el-button>
99 99
                       <el-button size="small" style="width: 100px">保存草稿</el-button>
100 100
                   <el-button size="small" style="width: 100px">取消</el-button>
101 101
                 </el-form-item>
@@ -104,65 +104,71 @@
104 104
         </el-form>
105 105
       </el-tab-pane>
106 106
       <el-tab-pane label="视频">
107
-        <el-form label-width="80px" class="clearfix">
107
+        <el-form label-width="100px" class="clearfix"  :rules="rules" :model="form" ref="vidoform">
108 108
            <el-row>
109 109
              <el-col :span="24">
110 110
                  <div style="margin-bottom: 100px">
111
-                 <el-form-item>
112
-                 <div class="video-select">
113
-                   <el-upload
114
-                   class="upload-demo"
115
-                   action="https://upload.qiniup.com"
116
-                   :on-preview="handlePreview"
117
-                   :on-remove="handleRemove"
118
-                   :before-remove="beforeRemove"
119
-                   multiple
120
-                   :limit="3"
121
-                   :on-exceed="handleExceed"
122
-                   :file-list="fileList"
123
-                   :before-upload="beforeUpload">
124
-                   <el-button size="small" type="primary">点击上传</el-button>
125
-                   <div slot="tip" class="el-upload__tip">只能上传jpg/exe文件,且不超过2G</div>
126
-                   </el-upload>
127
-                   </div>
128
-                   <div class="progressbar probar" style="text-align: center">
129
-                   <span class="videotitle"></span>
130
-                   <input type="hidden" name="videoUrl" id="videopath">
131
-                   <div class="barpic"></div>
132
-                   <span class="chaimg"></span>
133
-                   <span class="videoupload"></span>
134
-                   </div>
135
-                 </el-form-item>
111
+                   <el-form-item  required prop="vio_upload">
112
+                       <div class="video-select" v-if="show">
113
+                        <el-upload
114
+                            class="upload-demo"
115
+                            :data="uploadFileData"
116
+                            action="https://upload.qiniup.com"
117
+                            :on-change="handleChange"
118
+                            :on-success="handleSuccess"
119
+                            :on-error="handleError"
120
+                            :before-upload="beforeUploadFile"
121
+                             accept="video/x-flv,video/mpeg,video/avi,video/x-ms-wmv,video/quicktime,.asf,.rm,.rmvb,video/x-matroska,video/x-m4v,video/mp4">                         
122
+                             <el-button size="small" type="primary" v-if="show">点击上传</el-button>
123
+                             <div slot="tip" class="el-upload__tip" v-if="show">支持大多视频文件格式,大小不超过2G</div>
124
+                        </el-upload>
125
+                       </div>
126
+                         <div class="video" v-if="shows">
127
+                         <img v-if="form.vio_upload" :src="form.vio_upload+'?vframe/jpg/offset/1/w/300/h/200'" class="avatar" id="upvideo">
128
+                       </div>
129
+                        <div id="upvideo"></div>                  
130
+                    </el-form-item>
136 131
                   </div>
137
-                 <el-form-item label="视频标题:">
138
-                   <el-input placeholder="视频标题"></el-input>
132
+
133
+                 <el-form-item label="视频标题:" required prop="vid_name">
134
+                   <el-input v-model="form.vid_name"></el-input>
139 135
                  </el-form-item>
140
-                 <el-form-item label="视频封面:"></el-form-item>
141
-                 <el-form-item>
142
-                   <el-upload  class="avatar-uploader" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
143
-                     <img v-if="imageUrl" :src="imageUrl" class="avatar">
136
+
137
+                 <el-form-item label="视频封面:">
138
+                   <el-upload  class="avatar-uploader" :show-file-list="false" 
139
+                   :on-success="handlevioSuccess" 
140
+                   :before-upload="beforevidoFile" 
141
+                   :on-change="handleChange"
142
+                   action="https://upload.qiniup.com"
143
+                   :data="uploadvidoData">
144
+                     <img v-if="form.vid_pic" :src="form.vid_pic" class="avatar">                  
145
+                     <img v-if="form.vio_upload" :src="form.vio_upload+'?vframe/jpg/offset/1/w/300/h/200'" class="avatar">
144 146
                      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
145 147
                    </el-upload>
146 148
                  </el-form-item>
147
-                  <el-form-item label="所属分类:">
148
-                    <el-select v-model="form.act_type" placeholder="请选择">
149
+                 <div class="eltip">
150
+                   视频封面若不上传,系统会根据视频内容进行自动截取<br>
151
+                   目前支持PNG和JPG格式,图片大小不能超过1MB
152
+                   </div>
153
+                  <el-form-item label="所属分类:" required prop="vid_type">
154
+                    <el-select v-model="form.vid_type">
149 155
                       <el-option
150
-                         v-for="item in options"
151
-                         :key="item.value"
152
-                        :label="item.label"
153
-                         :value="item.value">
156
+                          v-for="item in options"
157
+                          :key="item.id"
158
+                          :label="item.name"
159
+                          :value="item.id"> 
154 160
                       </el-option>
155 161
                       </el-select>
156 162
                   </el-form-item>
157 163
                    <el-row :span="24">
158 164
                      <el-col :span="24">
159 165
                        <el-form-item>
160
-                         <el-button size="small" type="primary" style="width: 100px">发布</el-button>
161
-                         <el-button size="small" style="width: 100px">保存草稿</el-button>
162
-                         <el-button size="small" style="width: 100px">取消</el-button>
166
+                         <el-button size="small" type="primary" style="width: 100px" @click="SumitVido('vidoform');centerDialogVisible = false">发布</el-button>
167
+                         <el-button size="small" style="width: 100px" @click="Savedraft('vidoform');centerdraftVisible = false">保存草稿</el-button>
168
+                         <el-button size="small" style="width: 100px" @click="centercancelVisible = true">取消</el-button>
163 169
                        </el-form-item>
164 170
                      </el-col>
165
-                   </el-row>
171
+                   </el-row>                   
166 172
              </el-col>
167 173
            </el-row>
168 174
         </el-form>
@@ -175,12 +181,33 @@
175 181
         :visible.sync="centerDialogVisible"
176 182
          width="30%"
177 183
          center>
178
-         <!-- <span>需要注意的是内容是默认不居中的</span> -->
179 184
          <span slot="footer" class="dialog-footer">
180
-        <el-button @click="gotolink;centerDialogVisible = false">再发一条</el-button>
185
+        <el-button @click="gotolink()">再发一条</el-button>
181 186
         <el-button type="primary" @click="gobacklist">返回文章列表</el-button>
182 187
        </span>
183 188
       </el-dialog>
189
+
190
+      <el-dialog
191
+       title="保存草稿成功"
192
+       :visible.sync = "centerdraftVisible"
193
+        width="30%"
194
+        center>
195
+        <span slot="footer" class="dialog-footer">
196
+        <el-button type="primary" @click="gobacklist">返回文章列表</el-button>  
197
+         </span>
198
+      </el-dialog>
199
+
200
+      <el-dialog
201
+       title="提示"
202
+       :visible.sync = "centercancelVisible"
203
+       width="30%"
204
+       center>
205
+       <span style="center">是否确定取消编辑此文章/视频</span>
206
+       <span slot="footer" class="dialog-footer">
207
+       <el-button type="primary" @click="centercancelVisible = false" >确认</el-button>
208
+       <el-button @click="centercancelVisible = false">取消</el-button>   
209
+        </span>   
210
+      </el-dialog>
184 211
   </div>
185 212
 </template>
186 213
 
@@ -191,7 +218,7 @@
191 218
   import 'quill/dist/quill.snow.css'
192 219
   import 'quill/dist/quill.bubble.css'
193 220
   import Neditor from '@/components/Neditor'
194
-  import {submitForm,getArticleType} from '@/api/act/submitinfo'
221
+  import {submitForm,getArticleType,addVido,Savedraft} from '@/api/act/submitinfo'
195 222
   import { getToken } from '@/api/qiniu'
196 223
   import { getFileExtension} from '@/utils/tools'
197 224
   export default {
@@ -212,12 +239,8 @@
212 239
         show:false,
213 240
         content: '',
214 241
         editorOption: {},
215
-        uploadUrl:"",//你要上传视频到你后台的地址
216
-        videoFlag:false , //是否显示进度条
217
-        videoUploadPercent:"", //进度条的进度,
218
-        isShowUploadVideo:false, //显示上传按钮
219 242
         company:"",
220
-        fileList: [{name: '123', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}],
243
+        fileList: [],
221 244
         form:{
222 245
           act_name:'',
223 246
           act_content:'',
@@ -225,6 +248,11 @@
225 248
           act_category:'',
226 249
           org_logo:'',
227 250
           act_type:'',
251
+          file:'',
252
+          vid_pic:'',
253
+          vio_upload:'',
254
+          vid_name:'',
255
+          vid_type:'',
228 256
         },
229 257
          acttypes:[],
230 258
          imageUrl:'',
@@ -236,31 +264,37 @@
236 264
          uploading:false,
237 265
          loadingText:'',
238 266
          uploadData: { token: '', key: '' },
239
-         myConfig: {
240
-                // 如果需要上传功能,找后端小伙伴要服务器接口地址
241
-                serverUrl: '/api/web/upload/ueditor',
242
-                // 你的UEditor资源存放的路径,相对于打包后的index.html
243
-                UEDITOR_HOME_URL: '/NEditor/',
244
-                // 编辑器不自动被内容撑高
245
-                autoHeightEnabled: false,
246
-                // 初始容器高度
247
-                initialFrameHeight: 240,
248
-                // 初始容器宽度
249
-                initialFrameWidth: '100%',
250
-                // 关闭自动保存
251
-                enableAutoSave: false
252
-            },
267
+         uploadFileData:{token:'',key:''},
268
+         uploadvidoData:{token:'',key:''},
253 269
          centerDialogVisible: false,
270
+         centerdraftVisible:false,
271
+         centercancelVisible:false,
272
+         formLabelAlign:true,
273
+         modlevidel:'',
274
+         filsListArray:[],
275
+         show:true,
276
+         shows:false,
277
+         rules: {
278
+            vid_name: [{required: true, message: "视频标题不能为空"},],
279
+            vio_upload: [{required: true,message:"请上传视频"}],
280
+            vid_type: [{required: true,message:"所属分类不能为空"}]
281
+          },
282
+        artilcrules:{
283
+            act_name: [{required: true, message: "文章标题不能为空"},],
284
+            act_content: [{required: true,message:"文章内容不能为空"}],
285
+            act_type: [{required: true,message:"所属分类不能为空"}]
286
+        },
287
+        vidoform:[],
288
+        ue:'',
254 289
       }
255 290
     },
256 291
     created(){
257
-        this.getArticleType()
292
+        this.getArticleType();
258 293
     },
259 294
     methods: {
260 295
       //第一个图片
261 296
       handleAvatarSuccess(res, file) {
262
-        this.imageUrl = URL.createObjectURL(file.raw);
263
-        this.form.org_logo = this.qiniuDomain + res.url;
297
+       this.form.org_logo = this.qiniuDomain + res.url;
264 298
         this.uploading = false
265 299
       },
266 300
        handleAvatarError(err, file, fileList) {
@@ -298,8 +332,6 @@
298 332
                     this.uploading = false;
299 333
                 })
300 334
             })
301
-
302
-          //return isJPG && isLt2M;
303 335
       },
304 336
       //第二个图片
305 337
       handleAvatartwoSuccess(res, file) {
@@ -347,7 +379,6 @@
347 379
       },
348 380
 
349 381
       //第三张图片
350
-      //第二个图片
351 382
       handleAvatarlastSuccess(res, file) {
352 383
         this.imageUrlLast = URL.createObjectURL(file.raw);
353 384
         this.form.org_logo = this.qiniuDomain + res.url;
@@ -372,7 +403,6 @@
372 403
             var date = new Date()
373 404
             var ext = getFileExtension(file.name)
374 405
             var key = date.getFullYear() + (date.getMonth() + 1) + date.getDate() + date.getHours()  + date.getMinutes()  + date.getSeconds()  +'_o_' + file.uid + '.' + ext;
375
-            this.uploading = true;
376 406
             this.loadingText = '封面图片上传中'
377 407
 
378 408
             const _self = this
@@ -385,32 +415,76 @@
385 415
                     resolve(true)
386 416
                 }).catch(err => {
387 417
                     reject(false)
388
-                    this.uploading = false;
389 418
                 })
390
-            })
419
+            }) 
420
+        }, 
421
+        //视频上传
422
+        handleChange(file, fileList) {
423
+          this.form.file =  file.raw
424
+        }, 
425
+        handleSuccess(res,file,fileList){  
426
+            this.$message.success("视频上传成功")               
427
+             this.form.vio_upload = this.qiniuDomain + res.url;           
428
+             console.log("是什么",this.form.vio_upload)
391 429
 
392
-          //return isJPG && isLt2M;
430
+             this.show=false;
431
+             this.shows = true;
432
+        },
433
+        handlevioSuccess(res,file,fileList){
434
+           this.form.vid_pic = this.qiniuDomain + res.url;  
435
+        },
436
+        changeImg(url){
437
+          console.log("路径是多少?",url)
438
+        },
439
+         handleError(err, file, fileList) {
440
+             this.$message.error("视频上传失败")
441
+         },
442
+        beforeUploadFile(file) {
443
+        const isLt2M = file.size / 1024 / 1024 < 2048;
444
+        if (!isLt2M) {
445
+          this.$message.error('上传视频大小不能超过 2G!');
446
+        }
447
+            var date = new Date()
448
+            var ext = getFileExtension(file.name)
449
+            var key = date.getFullYear() + (date.getMonth() + 1) + date.getDate() + date.getHours()  + date.getMinutes()  + date.getSeconds()  +'_o_' + file.uid + '.' + ext;
450
+            const _self = this
451
+            return new Promise((resolve, reject) => {
452
+                getToken().then(response => {
453
+                    const token = response.data.data.uptoken
454
+                    //console.log("token2是什么?",token)
455
+                    _self._data.uploadFileData.token = token
456
+                    _self._data.uploadFileData.key = key
457
+                    resolve(true)
458
+                }).catch(err => {
459
+                    reject(false)                  
460
+                })
461
+            })
393 462
       },
394
-
395
-      beforeUpload(file) {
396
-        var testmsg=file.name.substring(file.name.lastIndexOf('.')+1)
397
-        const extension = testmsg === 'mp4'
398
-        const extension2 = testmsg === 'exe'
399
-        const isLt2M = file.size / 1024 / 1024 < 2048     //这里做文件大小限制
400
-        if(!extension && !extension2) {
401
-          this.$message({
402
-            message: '上传文件只能是 mp4、exe格式!',
403
-            type: 'warning'
404
-          });
463
+      beforevidoFile(file){
464
+          const isJPG = file.type === 'png/jpg';
465
+          if (!isJPG) {
466
+          this.$message.error('上传头像图片只能是 png或者jpg格式!');
405 467
         }
406
-        if(!isLt2M) {
407
-          this.$message({
408
-            message: '上传文件大小不能超过 2G!',
409
-            type: 'warning'
410
-          });
468
+          const isLt2M = file.size / 1024 / 1024 < 1;
469
+        if (!isLt2M) {
470
+          this.$message.error('上传视频大小不能超过 1M!');
411 471
         }
412
-        return extension || extension2 && isLt2M
413
-      },
472
+            var date = new Date()
473
+            var ext = getFileExtension(file.name)
474
+            var key = date.getFullYear() + (date.getMonth() + 1) + date.getDate() + date.getHours()  + date.getMinutes()  + date.getSeconds()  +'_o_' + file.uid + '.' + ext;
475
+            const _self = this
476
+            return new Promise((resolve, reject) => {
477
+                getToken().then(response => {
478
+                    const token = response.data.data.uptoken
479
+                    //console.log("token2是什么?",token)
480
+                    _self._data.uploadvidoData.token = token
481
+                    _self._data.uploadvidoData.key = key
482
+                    resolve(true)
483
+                }).catch(err => {
484
+                    reject(false)                  
485
+                })
486
+            })
487
+       },
414 488
       select(){
415 489
         this.show = false
416 490
       },
@@ -432,40 +506,74 @@
432 506
       changeActtype(){
433 507
          console.log("所属分类",this.form.act_type)
434 508
       },
435
-      submitForm(){
436
-        console.log("提交文章")
437
-        var params  = new Object()
438
-        params.act_name = this.form.act_name
439
-        params.act_content = this.$refs.neditor.content
440
-        params.org_logo = this.form.org_logo
441
-        params.act_type = this.form.act_type
442
-        this.formloading=true
443
-        this.submitForm =true
444
-        console.log("文章标题",params.act_name)
445
-        console.log("文章内容",params.act_content)
446
-        console.log("富文本编辑器的内容",params.act_content)
447
-        console.log("图片",params.org_logo)  
448
-        console.log("所属分类",params.act_type)    
449
-        submitForm(params).then(response => {
450
-         
451
-        })
509
+      submitForm(formName){
510
+        this.form.act_content = this.$refs.neditor.content;
511
+        console.log("文章内容",this.$refs.neditor.content)
512
+        this.$refs[formName].validate((valid)=>{
513
+            if(valid){
514
+              submitForm(this.form).then(response => {
515
+                   if(response.data.state == 1){
516
+                     this.centerDialogVisible = true;
517
+                     var articles = response.data.data.articles;
518
+                     console.log("返回的数据是啥?",articles);
519
+                   }
520
+              })
521
+            }
522
+        });
452 523
       },
453 524
       getArticleType(){
454 525
         getArticleType().then(response =>{
455
-            //console.log("好嗨我")
526
+            console.log(response.data.state)
456 527
             if(response.data.state === 1){
457 528
             var category = response.data.data.category
458 529
             this.options = response.data.data.category
459
-            // console.log("文章内容:",category)
460
-            // console.log("文章",this.options)
530
+             //console.log("文章内容:",category)
531
+             //console.log("文章",this.options)
461 532
             }
462 533
         })
463 534
       },
464 535
       gotolink(){
465
-        this.$router.push({path:"/articles/createArticle"})
536
+         this.$router.go(0);
466 537
       },
467 538
       gobacklist(){
468 539
         this.$router.push({path:'/articles/articleList'})
540
+      },
541
+      SumitVido(formName){
542
+         this.$refs[formName].validate((valid)=>{
543
+           if(valid){
544
+               addVido(this.form).then(response=>{
545
+                   if(response.data.state == 1){
546
+                     this.centerDialogVisible = true;
547
+                     var vido = response.data.data.vido;
548
+                     console.log("返回数据",vido)
549
+                   }
550
+               });
551
+           }
552
+         });
553
+      },
554
+      Savedraft(formName){
555
+        this.$refs[formName].validate((valid)=>{
556
+           if(valid){
557
+               Savedraft(this.form).then(response=>{
558
+                   if(response.data.state==1){
559
+                     this.centerdraftVisible = true;
560
+                     var savedraft = response.data.data.savedraft;
561
+                     console.log("保存草稿数据",savedraft)
562
+                   }
563
+               });
564
+           }
565
+        });
566
+      },
567
+      preview(formName){
568
+         this.form.act_content = this.$refs.neditor.content;
569
+         console.log("文章内容",this.$refs.neditor.content)
570
+         this.$refs[formName].validate((valid)=>{
571
+            if(valid){
572
+               preview(this.form).then(response=>{
573
+                    this.$router.go(0);
574
+               });
575
+            }
576
+         });
469 577
       }
470 578
     },
471 579
   }
@@ -507,6 +615,24 @@
507 615
     height: 200px;
508 616
     position: relative;
509 617
     left: 500px;
618
+    margin-bottom: 1px;
619
+  }
620
+  .video{
621
+    padding: 150px 0 30px;
622
+    background-position: center 0;
623
+    background-size: 192px 132px;
624
+    text-align: center;
625
+    width: 200px;
626
+    height: 200px;
627
+    position: relative;
628
+    left: 500px;
629
+    margin-bottom: 60px;
630
+    margin-top: -140px;
631
+  }
632
+  .eltip{
633
+    font-size: 12px;
634
+    position: relative;
635
+    left: 80px;
636
+    margin-bottom: 20px;
510 637
   }
511
-
512 638
 </style>

+ 265 - 0
src/scrm_pages/marketing_tool/activity_detail.vue ファイルの表示

@@ -0,0 +1,265 @@
1
+<template>
2
+    <div class="main-contain">
3
+        <div class="position">
4
+            <bread-crumb :crumbs="crumbs"></bread-crumb>
5
+        </div>
6
+        <div class="app-container" style="padding-top: 0; background-color: #f6f8f9;">
7
+            <div class="base-info">
8
+                <div class="poster-photo">
9
+                    <img :src="poster_photo" />
10
+                </div>
11
+                <div class="title-panel">
12
+                    <p class="title">
13
+                        <!-- <router-link v-if="activity != null && activity.status == 4" :to="activity_url" target="_blank">{{ title }}</router-link>
14
+                        <router-link v-else :to="activity_url">{{ title }}</router-link> -->
15
+                        <router-link :to="activity_url" target="_blank">{{ title }}</router-link>
16
+                    </p>
17
+                    <p class="date">活动日期:{{ activity_time }}</p>
18
+                </div>
19
+                <div class="action-panel">
20
+                    <el-button type="primary" v-if="show_share_btn" @click="$router.push({ path: '/activity/share', query: { id: activity_id } })">再次分享</el-button>
21
+                    <el-button type="primary" v-if="show_publish_btn" @click="publishActivity" :loading="publishing">发布</el-button>
22
+                </div>
23
+            </div>
24
+            <div class="times-statistics">
25
+                <el-row :gutter="20">
26
+                    <el-col :span="12">
27
+                        <div class="item">
28
+                            <span class="count">{{ read_times }}</span>
29
+                            <p class="desc">展示次数</p>
30
+                        </div>
31
+                    </el-col>
32
+                    <el-col :span="12">
33
+                        <div class="item">
34
+                            <span class="count">{{ join_count }}</span>
35
+                            <p class="desc">参与人数</p>
36
+                        </div>
37
+                    </el-col>
38
+                </el-row>
39
+            </div>
40
+            <div class="signup-header">
41
+                <div class="input">
42
+                    <el-input v-model="signup_keyword" placeholder="搜索报名人" style="width: 330px;"></el-input>
43
+                    <el-button type="primary" icon="el-icon-search" :loading="loading_search" @click="fetchSignupUsers">搜索</el-button>
44
+                </div>
45
+                <div class="all-btn">
46
+                    <el-button type="primary" @click="$router.push({ path: '/activity/signupusers', query: { id: activity_id } })">查看全部</el-button>
47
+                </div>
48
+            </div>
49
+            <div class="signup-table-panel">
50
+                <el-table :data="signup_users" empty-text="暂无人报名">
51
+                    <el-table-column label="报名号" align="center" prop="id"></el-table-column>
52
+                    <el-table-column label="手机号" align="center" prop="mobile"></el-table-column>
53
+                    <el-table-column label="客户姓名" align="center" prop="real_name"></el-table-column>
54
+                    <el-table-column label="报名时间" align="center">
55
+                        <template slot-scope="scope">
56
+                            <span>{{ parseTime(scope.row.ctime, "{y}-{m}-{d} {h}:{i}") }}</span>
57
+                        </template>
58
+                    </el-table-column>
59
+                </el-table>
60
+            </div>
61
+        </div>
62
+    </div>
63
+</template>
64
+
65
+<script>
66
+import BreadCrumb from "@/scrm_pages/components/bread-crumb"
67
+import { fetchActivityDetailViewData, fetchActivitySignupUsers, publishActivity } from "@/api/activity/activity"
68
+import { parseTime } from "@/utils"
69
+
70
+export default {
71
+    name: "ActivityDetail",
72
+    components: {
73
+        BreadCrumb,
74
+    },
75
+    data() {
76
+        return {
77
+            crumbs: [
78
+                { path: false, name: "营销工具" },
79
+                { path: false, name: "活动详情" },
80
+            ],
81
+
82
+            activity_id: 0,
83
+            activity: null,
84
+
85
+            signup_keyword: "",
86
+            signup_users: [],
87
+
88
+            loading_search: false,
89
+            publishing: false,
90
+        }
91
+    },
92
+    computed: {
93
+        title: function() {
94
+            return this.activity == null ? "" : this.activity.title
95
+        },
96
+        poster_photo: function() {
97
+            return this.activity == null ? "/" : this.activity.poster_photo
98
+        },
99
+        activity_url: function() {
100
+            if (this.activity != null) {
101
+                return "/activity/preview?id=" + this.activity_id
102
+            }
103
+            return ""
104
+        },
105
+        activity_time: function() {
106
+            return this.activity == null ? "" : parseTime(this.activity.start_time, "{y}-{m}-{d} {h}:{i}")
107
+        },
108
+        show_share_btn: function() {
109
+            return this.activity == null ? false : (this.activity.status == 1)
110
+        },
111
+        show_publish_btn: function() {
112
+            return this.activity == null ? false : (this.activity.status == 4)
113
+        },
114
+        read_times: function() {
115
+            return this.activity == null ? 0 : this.activity.read_num
116
+        },
117
+        join_count: function() {
118
+            return this.activity == null ? 0 : this.activity.join_num
119
+        }
120
+    },
121
+    mounted() {
122
+        this.activity_id = this.$route.query.id
123
+
124
+        fetchActivityDetailViewData(this.activity_id).then(rs => {
125
+            var resp = rs.data
126
+            if (resp.state == 1) {
127
+                this.activity = resp.data.activity
128
+                this.signup_users = resp.data.users
129
+            } else {
130
+                this.$message.error(resp.msg)
131
+            }
132
+
133
+        }).catch(err => {
134
+            this.$message.error(err)
135
+        })
136
+    },
137
+    methods: {
138
+        parseTime,
139
+        fetchSignupUsers: function() {
140
+            this.loading_search = true
141
+            fetchActivitySignupUsers(this.activity_id, this.signup_keyword, 1).then(rs => {
142
+                this.loading_search = false
143
+                var resp = rs.data
144
+                if (resp.state == 1) {
145
+                    this.signup_users = resp.data.users
146
+                } else {
147
+                    this.$message.error(resp.msg)
148
+                }
149
+            }).catch(err => {
150
+                this.loading_search = false
151
+                this.$message.error(err)
152
+            })
153
+        },
154
+        publishActivity: function() {
155
+            this.publishing = true
156
+            publishActivity(this.activity_id).then(rs => {
157
+                this.publishing = false
158
+                var resp = rs.data
159
+                if (resp.state == 1) {
160
+                    this.activity.status = 1
161
+                } else {
162
+                    this.$message.error(resp.msg)
163
+                } 
164
+
165
+            }).catch(rs => {
166
+                this.publishing = false
167
+                this.$message.error(err)
168
+            })
169
+        }
170
+    },
171
+}
172
+</script>
173
+
174
+<style lang="scss" scoped>
175
+.base-info {
176
+    padding: 20px 25px;
177
+    display: flex;
178
+    justify-content: flex-end;
179
+    flex-wrap: nowrap;
180
+    align-items: center;
181
+    background-color: white;
182
+    box-shadow: 0 0 1px #dee2e5;
183
+
184
+    .poster-photo {
185
+        width: 120px;
186
+        height: 96px;
187
+        display: flex;
188
+        justify-content: center;
189
+        margin-right: 22px;
190
+
191
+        img {
192
+            width: 100%;
193
+            height: auto;
194
+            border-radius: 4px;
195
+            object-fit: cover;
196
+            object-position: center;
197
+        }
198
+    }
199
+    .title-panel {
200
+        flex: 3;
201
+        padding-right: 20px;
202
+
203
+        .title {
204
+            font-size: 18px;
205
+            color: #485b6d;
206
+            font-weight: 700;
207
+            word-break: break-all;
208
+            overflow: hidden;
209
+            text-overflow: ellipsis;
210
+            display: -webkit-box;
211
+            -webkit-line-clamp: 2;
212
+            -webkit-box-orient: vertical;
213
+            height: 70px;
214
+            line-height: 34px;
215
+        }
216
+        .date {
217
+            color: #7b8a97;
218
+            line-height: 20px;
219
+            font-size: 14px;
220
+        }
221
+    }
222
+    .action-panel {
223
+        flex: 1;
224
+        text-align: right;
225
+    }
226
+}
227
+.times-statistics {
228
+    margin-top: 20px;
229
+
230
+    .item {
231
+        padding: 40px 0 30px 0;
232
+        box-shadow: 0 0 1px #dee2e5;
233
+        background-color: white;
234
+        text-align: center;
235
+
236
+        .count {
237
+            font-size: 36px;
238
+            color: #58a2ec;
239
+        }
240
+        .desc {
241
+            margin-top: 5px;
242
+            font-size: 14px;
243
+            color: #485b6d;
244
+        }
245
+    }
246
+}
247
+.signup-header {
248
+    margin-top: 20px;
249
+    display: flex;
250
+    justify-content: space-between;
251
+
252
+    .input {
253
+        width: 500px;
254
+        display: block;
255
+    }
256
+    .all-btn {
257
+        display: block;
258
+    }
259
+}
260
+.signup-table-panel {
261
+    margin-top: 10px;
262
+}
263
+</style>
264
+
265
+

+ 23 - 4
src/scrm_pages/marketing_tool/activity_list.vue ファイルの表示

@@ -34,8 +34,10 @@
34 34
       <div>
35 35
         <template v-for="(activity, index) in activities">
36 36
           <published-cell v-if="activity.status == 1 || activity.status == 4" :key="index" :activity="activity"></published-cell>
37
-          <unapproved-cell v-else-if="activity.status == 3" :key="index" :activity="activity"></unapproved-cell>
38
-          <drafts-cell v-else-if="activity.status == 2" :key="index" :activity="activity"></drafts-cell>
37
+
38
+          <unapproved-cell v-else-if="activity.status == 3" :key="index" :activity="activity" @delete="deleteActivity(activity.id, index)"></unapproved-cell>
39
+
40
+          <drafts-cell v-else-if="activity.status == 2" :key="index" :activity="activity" @delete="deleteActivity(activity.id, index)"></drafts-cell>
39 41
         </template>
40 42
       </div>
41 43
       <div class="cell clearfix" style="padding-top: 15px;">
@@ -46,11 +48,11 @@
46 48
 </template>
47 49
 
48 50
 <script>
49
-import BreadCrumb from "@/scrm_pages/components/bread-crumb";
51
+import BreadCrumb from "@/scrm_pages/components/bread-crumb"
50 52
 import PublishedCell from "@/scrm_pages/marketing_tool/components/published_cell"
51 53
 import UnapprovedCell from "@/scrm_pages/marketing_tool/components/unapproved_cell"
52 54
 import DraftsCell from "@/scrm_pages/marketing_tool/components/drafts_cell"
53
-import { fetchActivities } from "@/api/activity/activity"
55
+import { fetchActivities, deleteActivity } from "@/api/activity/activity"
54 56
 
55 57
 export default {
56 58
   name: "ActivityList",
@@ -102,6 +104,23 @@ export default {
102 104
         this.$message.error(err)
103 105
       })
104 106
     },
107
+
108
+    deleteActivity(id, index) {
109
+      this.loading_activities = true
110
+      deleteActivity(id).then(rs => {
111
+        this.loading_activities = false
112
+        var resp = rs.data
113
+        if (resp.state == 1) {
114
+          this.activities.splice(index, 1)
115
+        } else {
116
+          this.$message.error(resp.msg)
117
+        }
118
+      }).catch(err => {
119
+        this.loading_activities = false
120
+        this.$message.error(err)
121
+        return err
122
+      })
123
+    }
105 124
   },
106 125
 };
107 126
 </script>

+ 325 - 0
src/scrm_pages/marketing_tool/activity_preview.vue ファイルの表示

@@ -0,0 +1,325 @@
1
+<template>
2
+<div style="background-color: #f6f8f9;">
3
+    <div class="main">
4
+        <div class="border title-panel">
5
+            <img :src="activity.poster_photo"/>
6
+            <div class="text">
7
+                <p class="title">{{ activity.title }}</p>
8
+                <p class="subtitle">{{ activity.subtitle }}</p>
9
+            </div>
10
+        </div>
11
+        <div class="org-info border">
12
+            <div class="logo">
13
+                <img :src="org.logo" />
14
+            </div>
15
+            <div class="info">
16
+                <p class="name">{{ org.name }}</p>
17
+                <p class="address">{{ activity.address }}</p>
18
+            </div>
19
+            <div class="arrow">
20
+                <img src="@/assets/img/sa_52.png" />
21
+            </div>
22
+        </div>
23
+        <div class="simple-cell border">
24
+            <div class="icon">
25
+                <img src="@/assets/img/sa_21.png" />
26
+            </div>
27
+            <div class="text">
28
+                <p>{{ parseTime(activity.start_time, "{y}-{m}-{d} {h}:{i}") }}</p>
29
+            </div>
30
+            <div class="arrow-panel">
31
+                <img src="@/assets/img/sa_52.png" />
32
+            </div>
33
+        </div>
34
+        <div class="simple-cell border" v-if="activity.phone_number.length > 0">
35
+            <div class="icon">
36
+                <img src="@/assets/img/sa_24.png" />
37
+            </div>
38
+            <div class="text">
39
+                <p>{{ activity.phone_number }}</p>
40
+            </div>
41
+            <div class="arrow-panel">
42
+                <img src="@/assets/img/sa_52.png" />
43
+            </div>
44
+        </div>
45
+        <div class="simple-cell border" v-if="activity.limit_num > 0">
46
+            <div class="title">
47
+                <p>活动名额</p>
48
+            </div>
49
+            <div class="detail">
50
+                <p>{{ activity.limit_num + "人" }}</p>
51
+            </div>
52
+        </div>
53
+
54
+        <div class="large-text-cell border" v-if="sign_up_notice.length > 0">
55
+            <div class="title">
56
+                <img src="@/assets/img/sa_25.png" />
57
+                <span>报名须知</span>
58
+            </div>
59
+            <p class="content" v-html="sign_up_notice">
60
+            </p>
61
+        </div>
62
+
63
+        <div class="large-text-cell border" v-if="activity_paragraph.title.length > 0">
64
+            <div class="title">
65
+                <img src="@/assets/img/sa_26.png" />
66
+                <span>{{ activity_paragraph.title }}</span>
67
+            </div>
68
+            <p class="content" v-html="activity_paragraph.content">
69
+            </p>
70
+        </div>
71
+
72
+        <div class="signup-fake-btn">
73
+            立即报名
74
+        </div>
75
+    </div>
76
+</div> 
77
+</template>
78
+
79
+<script>
80
+import { fetchActivity } from "@/api/activity/activity"
81
+import { parseTime } from "@/utils"
82
+
83
+export default {
84
+    name: "ActivityPreview",
85
+    data() {
86
+        return {
87
+            activity_id: 0,
88
+
89
+            activity: {
90
+                id: 0,
91
+                poster_photo: "",
92
+                title: "",
93
+                subtitle: "",
94
+                address: "",
95
+                limit_num: 0,
96
+                sign_up_deadline: 0,
97
+                start_time: 0,
98
+                phone_number: "",
99
+                sign_up_notice: "",
100
+            },
101
+            activity_paragraph: {
102
+                title: "",
103
+                content: "",
104
+            },
105
+            org: {
106
+                name: "",
107
+                logo: "",
108
+            }
109
+        }
110
+    },
111
+    computed: {
112
+        sign_up_notice: function() {
113
+            return this.activity.sign_up_notice.replace(/\n/g, "<br/>")
114
+        }
115
+    },
116
+    mounted() {
117
+        this.activity_id = this.$route.query.id
118
+
119
+        fetchActivity(this.activity_id).then(rs => {
120
+            var resp = rs.data
121
+            if (resp.state == 1) {
122
+                // console.log(resp.data)
123
+                var activity = resp.data.activity
124
+                this.activity.id = activity.id
125
+                this.activity.poster_photo = activity.poster_photo
126
+                this.activity.title = activity.title
127
+                this.activity.subtitle = activity.subtitle
128
+                this.activity.address = activity.address
129
+                this.activity.limit_num = activity.limit_num
130
+                this.activity.sign_up_deadline = activity.sign_up_deadline * 1000
131
+                this.activity.start_time = activity.start_time * 1000
132
+                this.activity.phone_number = activity.phone_number
133
+                this.activity.sign_up_notice = activity.sign_up_notice
134
+
135
+                var paragraph = resp.data.paragraph
136
+                this.activity_paragraph.title = paragraph.title
137
+                this.activity_paragraph.content = paragraph.content
138
+
139
+                this.org.name = resp.data.org.name
140
+                this.org.logo = resp.data.org.logo
141
+
142
+            } else {
143
+                this.$message.error(resp.msg)
144
+            }
145
+
146
+        }).catch(err => {
147
+            this.$message.error(err)
148
+        })
149
+    },
150
+    methods: {
151
+        parseTime,
152
+    }
153
+}
154
+</script>
155
+
156
+<style lang="scss" scoped>
157
+.main {
158
+    width: 750px;
159
+    margin: 0 auto;
160
+    padding: 14px 30px 0 30px;
161
+
162
+    .title-panel {
163
+        background-color: white;
164
+
165
+        img {
166
+            width: 100%;
167
+            height: auto;
168
+        }
169
+        .text {
170
+            padding: 12px 15px 16px 20px;
171
+
172
+            .title {
173
+                font-size: 18px;
174
+                color: #485b6d;
175
+                font-weight: bold;
176
+                line-height: 32px;
177
+            }
178
+            .subtitle {
179
+                margin-top: 4px;
180
+                color: #a6a6a6;
181
+                font-size: 14px;
182
+            }
183
+        }
184
+    }
185
+
186
+    .org-info {
187
+        padding: 26px 20px;
188
+        position: relative;
189
+        display: flex;
190
+        -webkit-box-align: center;
191
+        align-items: center;
192
+        margin-top: 15px;
193
+        background-color: white;
194
+
195
+        .logo {
196
+            img {
197
+                width: 40px;
198
+                height: 40px;
199
+                border-radius: 20px;
200
+                object-fit: cover;
201
+                object-position: center;
202
+            }
203
+        }
204
+
205
+        .info {
206
+            flex: 1;
207
+            padding-left: 23px;
208
+            color: #485b6d;
209
+
210
+            .name {
211
+                font-size: 16px;
212
+                line-height: 22px;
213
+            }
214
+            .address {
215
+                font-size: 14px;
216
+                line-height: 20px;
217
+            }
218
+        }
219
+        
220
+        .arrow {
221
+            width: 20px;
222
+            position: relative;
223
+            img {
224
+                width: 8px;
225
+                float: right;
226
+            }
227
+        }
228
+    }
229
+
230
+    .simple-cell {
231
+        background-color: white;
232
+        padding: 20px 20px;
233
+        margin-top: 15px;
234
+        position: relative;
235
+        display: flex;
236
+        -webkit-box-align: center;
237
+        align-items: center;
238
+
239
+        .icon {
240
+            img {
241
+                width: 20px;
242
+                height: auto;//20px;
243
+                vertical-align: middle;
244
+            }
245
+        }
246
+        .text {
247
+            flex: 1;
248
+            padding-left: 17px;
249
+            color: #485b6d;
250
+            line-height: 20px;
251
+        }
252
+        .arrow-panel {
253
+            width: 20px;
254
+            position: relative;
255
+
256
+            img {
257
+                width: 8px;
258
+                float: right;
259
+                vertical-align: middle;
260
+            }
261
+        }
262
+
263
+        .title {
264
+            p {
265
+                color: #485b6d;
266
+            }
267
+        }
268
+        .detail {
269
+            flex: 1;
270
+            padding-left: 23px;
271
+            color: #485b6d;
272
+
273
+            p {
274
+                color: #485b6d;
275
+                float: right;
276
+                text-align: right;
277
+            }
278
+        }
279
+    }
280
+
281
+    .large-text-cell {
282
+        background-color: white;
283
+        padding: 20px 20px;
284
+        position: relative;
285
+        -webkit-box-align: center;
286
+        align-items: center;
287
+        margin-top: 15px;
288
+
289
+        .title {
290
+            color: #485b6d;
291
+            line-height: 18px;
292
+            height: 18px;
293
+
294
+            img {
295
+                margin-right: 11px;
296
+                float: left;
297
+            }
298
+        }
299
+        .content {
300
+            color: #a8b3ba;
301
+            margin: 10px 0 0 0;
302
+            font-size: 14px;
303
+            line-height: 20px;
304
+        }
305
+    }
306
+
307
+    .signup-fake-btn {
308
+        background: #58a1ed;
309
+        color: #fff;
310
+        height: 50px;
311
+        line-height: 50px;
312
+        text-align: center;
313
+        width: 100%;
314
+        margin-top: 100px;
315
+        font-size: 16px;
316
+    }
317
+}
318
+</style>
319
+
320
+<style scoped>
321
+.border {
322
+    border: solid 1px #dee2e5;
323
+    border-radius: 4px;
324
+}
325
+</style>

+ 36 - 1
src/scrm_pages/marketing_tool/activity_publish.vue ファイルの表示

@@ -9,7 +9,7 @@
9 9
                     <preview-form :activity="activity" :paragraph="activity_paragraph"></preview-form>
10 10
                 </div>
11 11
                 <div class="edit-panel">
12
-                    <edit-form :activity="activity" :paragraph="activity_paragraph"></edit-form>
12
+                    <edit-form ref="edit_form" :activity="activity" :paragraph="activity_paragraph"></edit-form>
13 13
                 </div>
14 14
             </div>
15 15
         </div>
@@ -20,6 +20,7 @@
20 20
 import BreadCrumb from "@/scrm_pages/components/bread-crumb";
21 21
 import PreviewForm from "@/scrm_pages/marketing_tool/components/edit_activity_preview_form"
22 22
 import EditForm from "@/scrm_pages/marketing_tool/components/edit_activity_edit_form"
23
+import { fetchActivity } from "@/api/activity/activity"
23 24
 
24 25
 export default {
25 26
     name: "ActivityPublish",
@@ -53,6 +54,40 @@ export default {
53 54
             }
54 55
         }
55 56
     },
57
+    created() {
58
+        var id = this.$route.query.id
59
+        if (id != undefined) {
60
+            fetchActivity(id).then(rs => {
61
+                var resp = rs.data
62
+                if (resp.state == 1) {
63
+                    // console.log(resp.data)
64
+                    var activity = resp.data.activity
65
+                    this.activity.id = activity.id
66
+                    this.activity.poster_photo = activity.poster_photo
67
+                    this.activity.title = activity.title
68
+                    this.activity.subtitle = activity.subtitle
69
+                    this.activity.address = activity.address
70
+                    this.activity.limit_num = activity.limit_num
71
+                    this.activity.sign_up_deadline = activity.sign_up_deadline * 1000
72
+                    this.activity.start_time = activity.start_time * 1000
73
+                    this.activity.phone_number = activity.phone_number
74
+                    this.activity.sign_up_notice = activity.sign_up_notice
75
+
76
+                    var paragraph = resp.data.paragraph
77
+                    this.activity_paragraph.title = paragraph.title
78
+                    this.activity_paragraph.content = paragraph.content
79
+
80
+                    this.$refs.edit_form.initForms()
81
+
82
+                } else {
83
+                    this.$message.error(resp.msg)
84
+                }
85
+
86
+            }).catch(err => {
87
+                this.$message.error(err)
88
+            })
89
+        }
90
+    },
56 91
 }
57 92
 </script>
58 93
 

+ 227 - 0
src/scrm_pages/marketing_tool/activity_share.vue ファイルの表示

@@ -0,0 +1,227 @@
1
+<template>
2
+    <div class="main-contain">
3
+        <div class="position">
4
+            <bread-crumb :crumbs="crumbs"></bread-crumb>
5
+        </div>
6
+        <div class="app-container" style="padding: 0 6px 20px; background-color: #f6f8f9;">
7
+            <div class="wx-share-panel">
8
+                <div class="text-panel">
9
+                    <p class="title">微信分享</p>
10
+                    <p class="desc">以微信方式推送给客户,该方式可以监测活动的展现及参与次数</p>
11
+                </div>
12
+                <div class="qrcode-panel">
13
+                    <div class="qrcode">
14
+                        <img :src="qr_img" :style="{ opacity: qr_img.length > 0 ? 1 : 0 }" />
15
+                    </div>
16
+                    <div class="btn">
17
+                        <el-button type="primary" @click="previewAction">新窗口预览</el-button>
18
+                    </div>
19
+                </div>
20
+            </div>
21
+            <div class="sms-share-panel">
22
+                <div class="text-panel">
23
+                    <p class="title">短信分享</p>
24
+                    <p class="desc">以短信方式推送给客户</p>
25
+                </div>
26
+                <div class="btn-panel">
27
+                    <el-button type="primary">短信推送</el-button>
28
+                </div>
29
+            </div>
30
+            <div class="link-share-panel">
31
+                <div>
32
+                    <p class="title">网页链接</p>
33
+                    <p class="desc">可以直接分享以下链接到相应媒体(邮件、QQ、微博等),或者嵌入到微信公众号菜单</p>
34
+                </div>
35
+                <div class="input-line">
36
+                    <div class="input">
37
+                        <el-input readonly v-model="short_url"></el-input>
38
+                    </div>
39
+                    <el-button type="primary" @click="copyAction">复制链接</el-button>
40
+                </div>
41
+            </div>
42
+        </div>
43
+    </div>
44
+</template>
45
+
46
+<script>
47
+import BreadCrumb from "@/scrm_pages/components/bread-crumb"
48
+import QRCode from "qrcode"
49
+import { getActivityShareInfo } from "@/api/activity/activity"
50
+
51
+export default {
52
+    name: "ActivityShare",
53
+    components: {
54
+        BreadCrumb,
55
+    },
56
+    data() {
57
+        return {
58
+            crumbs: [
59
+                { path: false, name: "活动详情" },
60
+                { path: false, name: "活动分享" },
61
+            ],
62
+
63
+            activity_id: 0,
64
+            short_url: "",
65
+            qr_img: "",
66
+        }
67
+    },
68
+    mounted() {
69
+        this.activity_id = this.$route.query.id
70
+
71
+        getActivityShareInfo(this.activity_id).then(rs => {
72
+            var resp = rs.data
73
+            if (resp.state == 1) {
74
+                this.short_url = resp.data.url
75
+
76
+                var opts = {
77
+                    errorCorrectionLevel: "H",
78
+                    type: "image/png"
79
+                };
80
+                var that = this;
81
+                QRCode.toDataURL(this.short_url, opts, function(err, qr_url) {
82
+                    if (err) {
83
+                        console.log(err);
84
+                    } else {
85
+                        that.qr_img = qr_url;
86
+                    }
87
+                });
88
+
89
+            } else {
90
+                this.$message.error(resp.msg)
91
+            }
92
+        }).catch(err => {
93
+            this.$message.error(err)
94
+        })
95
+
96
+    },
97
+    methods: {
98
+        previewAction: function () {
99
+            // var new_page = this.$router.resolve({ 
100
+            //     path: '/activity/preview',
101
+            //     query: {
102
+            //         id: this.activity_id,
103
+            //     }   
104
+            // })
105
+            // window.open(new_page.href, '_blank');
106
+            window.open(this.short_url, "_blank")
107
+        },
108
+        copyAction: function() {
109
+            var input = document.createElement("input");
110
+            input.value = this.short_url;
111
+            document.body.appendChild(input);
112
+            input.select();
113
+            document.execCommand("Copy");
114
+            document.body.removeChild(input);
115
+
116
+            this.$message.success("已复制链接")
117
+        }
118
+    },
119
+}
120
+</script>
121
+
122
+<style lang="scss" scoped>
123
+.wx-share-panel {
124
+    box-shadow: 0 0 1px #dee2e5;
125
+    padding: 25px 35px;
126
+    display: flex;
127
+    background-color: white;
128
+
129
+    .text-panel {
130
+        flex: 1;
131
+
132
+        .title {
133
+            font-size: 16px;
134
+            color: #485b6d;
135
+            font-weight: bold;
136
+            height: 40px;
137
+            display: -webkit-box;
138
+            -webkit-box-orient: vertical;
139
+            -webkit-line-clamp: 2;
140
+            overflow: hidden;
141
+        }
142
+        .desc {
143
+            color: #7b8a97;
144
+            font-size: 14px;
145
+        }
146
+    }
147
+    .qrcode-panel {
148
+        text-align: right;
149
+
150
+        .qrcode {
151
+            text-align: center;
152
+
153
+            img {
154
+                width: 120px;
155
+                height: 120px;
156
+            }
157
+        }
158
+
159
+        .btn {
160
+            text-align: center;
161
+        }
162
+    }
163
+}
164
+
165
+.sms-share-panel {
166
+    box-shadow: 0 0 1px #dee2e5;
167
+    padding: 25px 35px;
168
+    display: flex;
169
+    margin-top: 20px;
170
+    background-color: white;
171
+
172
+    .text-panel {
173
+        flex: 1;
174
+
175
+        .title {
176
+            font-size: 16px;
177
+            color: #485b6d;
178
+            font-weight: bold;
179
+            height: 40px;
180
+            display: -webkit-box;
181
+            -webkit-box-orient: vertical;
182
+            -webkit-line-clamp: 2;
183
+            overflow: hidden;
184
+        }
185
+        .desc {
186
+            color: #7b8a97;
187
+            font-size: 14px;
188
+        }
189
+    }
190
+    .btn-panel {
191
+        text-align: right;
192
+        padding-right: 4px;
193
+    }
194
+}
195
+
196
+.link-share-panel {
197
+    box-shadow: 0 0 1px #dee2e5;
198
+    padding: 25px 35px;
199
+    // display: flex;
200
+    margin-top: 20px;
201
+    background-color: white;
202
+
203
+    .title {
204
+        font-size: 16px;
205
+        color: #485b6d;
206
+        font-weight: bold;
207
+        height: 40px;
208
+        display: -webkit-box;
209
+        -webkit-box-orient: vertical;
210
+        -webkit-line-clamp: 2;
211
+        overflow: hidden;
212
+    }
213
+    .desc {
214
+        color: #7b8a97;
215
+        font-size: 14px;
216
+    }
217
+    .input-line {
218
+        margin-top: 20px;
219
+
220
+        .input {
221
+            display: inline-block;
222
+            width: 400px;
223
+        }
224
+    }
225
+}
226
+</style>
227
+

+ 107 - 0
src/scrm_pages/marketing_tool/activity_signup_users.vue ファイルの表示

@@ -0,0 +1,107 @@
1
+<template>
2
+    <div class="main-contain">
3
+        <div class="position">
4
+            <bread-crumb :crumbs="crumbs"></bread-crumb>
5
+        </div>
6
+        <div class="app-container" style="padding-top: 0; background-color: #f6f8f9;">
7
+            <div style="display: flex;">
8
+                <div style="flex: 1;">
9
+                    <router-link to="/activity/list">
10
+                        <el-button type="primary">返回列表</el-button>
11
+                    </router-link>
12
+                </div>
13
+                <el-button type="primary" @click="printAction">导出</el-button>
14
+            </div>
15
+            <div style="margin-top: 10px;" id="table-panel">
16
+                <el-table id="table" border :data="signup_users" empty-text="暂无人报名">
17
+                    <el-table-column label="报名号" align="center" prop="id"></el-table-column>
18
+                    <el-table-column label="手机号" align="center" prop="mobile"></el-table-column>
19
+                    <el-table-column label="客户姓名" align="center" prop="real_name"></el-table-column>
20
+                    <el-table-column label="报名时间" align="center">
21
+                        <template slot-scope="scope">
22
+                            <span>{{ parseTime(scope.row.ctime, "{y}-{m}-{d} {h}:{i}") }}</span>
23
+                        </template>
24
+                    </el-table-column>
25
+                </el-table>
26
+            </div>
27
+            <div style="margin-top: 10px;">
28
+                <el-pagination :total="total" :current-page.sync="current_page" :page-size="10" layout="total, prev, pager, next" @current-change="getActivities()"></el-pagination>
29
+            </div>
30
+            <div id="print-table" style="width:960px; display: none;">
31
+                <el-table border :data="signup_users" empty-text="暂无人报名">
32
+                    <el-table-column label="报名号" align="center" prop="id"></el-table-column>
33
+                    <el-table-column label="手机号" align="center" prop="mobile"></el-table-column>
34
+                    <el-table-column label="客户姓名" align="center" prop="real_name"></el-table-column>
35
+                    <el-table-column label="报名时间" align="center">
36
+                        <template slot-scope="scope">
37
+                            <span>{{ parseTime(scope.row.ctime, "{y}-{m}-{d} {h}:{i}") }}</span>
38
+                        </template>
39
+                    </el-table-column>
40
+                </el-table>
41
+            </div>
42
+        </div>
43
+    </div>
44
+</template>
45
+
46
+<script>
47
+import BreadCrumb from "@/scrm_pages/components/bread-crumb"
48
+import { fetchActivitySignupUsers } from "@/api/activity/activity"
49
+import { parseTime } from "@/utils"
50
+import printJS from "print-js"
51
+
52
+export default {
53
+    name: "ActivitySignupUsers",
54
+    components: {
55
+        BreadCrumb,
56
+    },
57
+    data() {
58
+        return {
59
+            crumbs: [
60
+                { path: false, name: "活动详情" },
61
+                { path: false, name: "报名列表" },
62
+            ],
63
+
64
+            activity_id: 0,
65
+
66
+            signup_users: [],
67
+            loading_search: false,
68
+            total: 0,
69
+            current_page: 1,
70
+        }
71
+    },
72
+    mounted() {
73
+        this.activity_id = this.$route.query.id
74
+
75
+        this.fetchSignupUsers()
76
+    },
77
+    methods: {
78
+        parseTime,
79
+        fetchSignupUsers: function() {
80
+            this.loading_search = true
81
+            fetchActivitySignupUsers(this.activity_id, "", this.current_page).then(rs => {
82
+                this.loading_search = false
83
+                var resp = rs.data
84
+                if (resp.state == 1) {
85
+                    this.signup_users = resp.data.users
86
+                    this.total = resp.data.total
87
+                } else {
88
+                    this.$message.error(resp.msg)
89
+                }
90
+            }).catch(err => {
91
+                this.loading_search = false
92
+                this.$message.error(err)
93
+            })
94
+        },
95
+        printAction: function() {
96
+            printJS({
97
+                printable: 'table',
98
+                type: "html",
99
+                scanStyles: false,
100
+                css: ['https://unpkg.com/element-ui/lib/theme-chalk/index.css'],
101
+                // maxWidth: 960,
102
+            })
103
+        },
104
+    },
105
+}
106
+</script>
107
+

+ 15 - 3
src/scrm_pages/marketing_tool/components/drafts_cell.vue ファイルの表示

@@ -7,11 +7,13 @@
7 7
         </div>
8 8
         <div class="activity-info-panel">
9 9
             <h3 class="title">
10
-                <a href="/">{{ activity.title }}</a>
10
+                <router-link :to="activityUrl">
11
+                    <a>{{ activity.title }}</a>
12
+                </router-link>
11 13
             </h3>
12 14
             <div class="operation">
13
-                <el-button type="primary" size="small" icon="el-icon-edit-outline">编辑</el-button>
14
-                <el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
15
+                <el-button type="primary" size="small" icon="el-icon-edit-outline" @click="$router.push({ path: '/activity/modify', query: {id: activity.id} })">编辑</el-button>
16
+                <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteActivity">删除</el-button>
15 17
             </div>
16 18
         </div>
17 19
     </div>
@@ -32,6 +34,16 @@ export default {
32 34
             
33 35
         }
34 36
     },
37
+    computed: {
38
+        activityUrl: function() {
39
+            return "/activity?id=" + this.activity.id
40
+        }
41
+    },
42
+    methods: {
43
+        deleteActivity() {
44
+            this.$emit("delete")
45
+        }
46
+    }
35 47
 }
36 48
 </script>
37 49
 

+ 127 - 11
src/scrm_pages/marketing_tool/components/edit_activity_edit_form.vue ファイルの表示

@@ -11,7 +11,7 @@
11 11
                     基本信息
12 12
                 </p>
13 13
                 <div class="module-item">
14
-                    <label class="item-title">主图</label>
14
+                    <label class="item-title">海报</label>
15 15
                     <div class="poster-photo-panel">
16 16
                         <el-input v-model="poster_photo_file_name" :readonly="true" class="input"></el-input>
17 17
                         <el-upload 
@@ -22,7 +22,7 @@
22 22
                         :on-success="posterPhotoUploadSuccess"
23 23
                         :before-upload="beforePosterPhotoUpload"
24 24
                         >
25
-                            <el-button type="primary" style="margin-left: 10px;" v-loading="uploading_poster_photo">上传图片</el-button>
25
+                            <el-button type="primary" style="margin-left: 10px;" :loading="uploading_poster_photo">上传图片</el-button>
26 26
                         </el-upload>
27 27
                     </div>
28 28
                 </div>
@@ -93,9 +93,9 @@
93 93
             </div>
94 94
 
95 95
             <div class="submit-button-panel">
96
-                <el-button style="padding: 10px 30px;" type="primary">发 布</el-button>
97
-                <el-button style="color: #409eff; border-color: #409eff; padding: 10px 30px;">保存草稿</el-button>
98
-                <el-button style="color: #409eff; border-color: #409eff; padding: 10px 30px;">预 览</el-button>
96
+                <el-button style="padding: 10px 30px;" type="primary" @click="publishAction" :loading="publishing_activity" :disabled="saving_activity || saving_before_preview_activity">发 布</el-button>
97
+                <el-button style="color: #409eff; border-color: #409eff; padding: 10px 30px;" @click="saveAction" :loading="saving_activity" :disabled="publishing_activity || saving_before_preview_activity">保存草稿</el-button>
98
+                <el-button style="color: #409eff; border-color: #409eff; padding: 10px 30px;" @click="previewAction" :loading="saving_before_preview_activity" :disabled="publishing_activity || saving_activity">预 览</el-button>
99 99
             </div>
100 100
         </div>
101 101
     </div>
@@ -105,6 +105,8 @@
105 105
 import Neditor from '@/components/Neditor'
106 106
 import { getToken } from "@/api/qiniu"
107 107
 import { getFileExtension } from "@/utils/tools"
108
+import { parseTime } from "@/utils"
109
+import { submitActivity } from "@/api/activity/activity"
108 110
 
109 111
 export default {
110 112
     name: "EditActivityEditForm",
@@ -123,6 +125,10 @@ export default {
123 125
     },
124 126
     data() {
125 127
         return {
128
+            saving_activity: false,
129
+            publishing_activity: false,
130
+            saving_before_preview_activity: false,
131
+
126 132
             uploading_poster_photo: false,
127 133
             qntoken: "",
128 134
             poster_photo_file_key: "",
@@ -153,14 +159,19 @@ export default {
153 159
             }
154 160
         },
155 161
         activity_time: function(new_val) {
156
-            this.activity.start_time = new_val
162
+            this.activity.start_time = parseInt(new_val / 1000)
157 163
         },
158 164
         sign_up_deadline: function(new_val) {
159
-            this.activity.sign_up_deadline = new_val  
165
+            this.activity.sign_up_deadline = parseInt(new_val / 1000)
160 166
         },
161 167
     },
162 168
     methods: {
163
-        initParagraphContent: function(content) {
169
+        initForms: function() {
170
+            this.poster_photo_file_name = this.activity.poster_photo
171
+            this.limit_num = this.activity.limit_num > 0 ? this.activity.limit_num : ""
172
+            this.activity_time = this.activity.start_time
173
+            this.sign_up_deadline = this.activity.sign_up_deadline
174
+
164 175
             this.paragraph_init_content = this.paragraph.content
165 176
         },
166 177
         paragraphContentChanged: function(content) {
@@ -172,14 +183,11 @@ export default {
172 183
             this.$message.error(err)
173 184
         },
174 185
         posterPhotoUploadSuccess: function(res, file) {
175
-            console.log(res)
176
-            console.log(file)
177 186
             this.poster_photo_file_name = file.name
178 187
             this.uploading_poster_photo = false
179 188
             this.activity.poster_photo = "https://images.shengws.com/" + res.url
180 189
         },
181 190
         beforePosterPhotoUpload: function(file) {
182
-            console.log(file)
183 191
             var is_image = file.type.indexOf("image") > -1
184 192
             var mb = file.size / 1024 / 1024
185 193
 
@@ -211,6 +219,114 @@ export default {
211 219
                 })
212 220
             })
213 221
         },
222
+
223
+        saveAction: function() {
224
+            this.saving_activity = true
225
+            this.submitActivity(false, function() {
226
+                // 弹框 => 再发一条/前往列表
227
+            })
228
+        },
229
+        publishAction: function() {
230
+            this.publishing_activity = true
231
+            this.submitActivity(true, function() {
232
+                this.$router.push({ path: "/activity", query: { id: this.activity.id } })
233
+            })
234
+        },
235
+        previewAction: function() {
236
+            this.saving_before_preview_activity = true
237
+            var t = this
238
+            this.submitActivity(false, function() {
239
+                var new_page = t.$router.resolve({ 
240
+                    path: '/activity/preview',
241
+                    query: {
242
+                        id: t.activity.id,
243
+                    }   
244
+                })
245
+                window.open(new_page.href, '_blank');
246
+            })
247
+        },
248
+        submitActivity: function(is_publish, successCallBack) {
249
+            this.validActivityInfo().then(() => {
250
+                var activity = {
251
+                    id: this.activity.id,
252
+                    poster_photo: this.activity.poster_photo,
253
+                    title: this.activity.title,
254
+                    subtitle: this.activity.subtitle,
255
+                    address: this.activity.address,
256
+                    limit_num: this.activity.limit_num,
257
+                    sign_up_deadline: parseTime(this.activity.sign_up_deadline, "{y}-{m}-{d} {h}:{i}"),
258
+                    start_time: parseTime(this.activity.start_time, "{y}-{m}-{d} {h}:{i}"),
259
+                    phone_number: this.activity.phone_number,
260
+                    sign_up_notice: this.activity.sign_up_notice,
261
+
262
+                    paragraph: {
263
+                        title: this.paragraph.title,
264
+                        content: this.paragraph.content,
265
+                    }
266
+                }
267
+                submitActivity(is_publish, activity).then(rs => {
268
+                    var resp = rs.data
269
+                    if (resp.state == 1) {
270
+                        this.activity.id = resp.data.activity_id
271
+                    } else {
272
+                        this.$message.error(resp.msg)
273
+                    }
274
+
275
+                    if (successCallBack != null || successCallBack != undefined) {
276
+                        successCallBack()
277
+                    }
278
+
279
+                    this.saving_activity = false
280
+                    this.publishing_activity = false
281
+                    this.saving_before_preview_activity = false
282
+
283
+                }).catch(err => {
284
+                    console.log('------  ' + err)
285
+                    this.$message.error(err)
286
+                    this.saving_activity = false
287
+                    this.publishing_activity = false
288
+                    this.saving_before_preview_activity = false
289
+                })
290
+
291
+            }).catch(err => {
292
+                console.log('asdada  ' + err)
293
+                this.$message.error(err)
294
+                this.saving_activity = false
295
+                this.publishing_activity = false
296
+                this.saving_before_preview_activity = false
297
+            })
298
+        },
299
+        validActivityInfo: function() {
300
+            return new Promise((resolve, reject) => {
301
+                if (this.activity.poster_photo.length == 0) {
302
+                    reject("海报不能为空")
303
+                    return
304
+                } else if (this.activity.title.length == 0) {
305
+                    reject("标题不能为空")
306
+                    return
307
+                } else if (this.activity.subtitle.length == 0) {
308
+                    reject("副标题不能为空")
309
+                    return
310
+                } else if (this.activity.address.length == 0) {
311
+                    reject("活动地址不能为空")
312
+                    return
313
+                } else if (this.activity.sign_up_deadline == 0) {
314
+                    reject("活动报名时间不能为空")
315
+                    return
316
+                } else if (this.activity.start == 0) {
317
+                    reject("活动时间不能为空")
318
+                    return
319
+                } else {
320
+                    if (this.activity.phone_number.length > 0) {
321
+                        if (/^1\d{10}$/.test(this.activity.phone_number) == false && /^(0\d{2,3}-?\d{7,8}$)/.test(this.activity.phone_number) == false) {
322
+                            reject("联系方式格式错误")
323
+                            return
324
+                        }
325
+                    }
326
+                }
327
+                resolve()
328
+            })
329
+        },
214 330
     },
215 331
 }
216 332
 </script>

+ 2 - 0
src/scrm_pages/marketing_tool/components/edit_activity_preview_form.vue ファイルの表示

@@ -197,6 +197,8 @@ export default {
197 197
                     width: 40px;
198 198
                     height: 40px;
199 199
                     border-radius: 20px;
200
+                    object-fit: cover;
201
+                    object-position: center;
200 202
                 }
201 203
             }
202 204
             .text-info {

+ 7 - 2
src/scrm_pages/marketing_tool/components/published_cell.vue ファイルの表示

@@ -7,7 +7,9 @@
7 7
         </div>
8 8
         <div class="activity-info-panel">
9 9
             <h3 class="title">
10
-                <a href="">{{ activity.title }}</a>
10
+                <router-link :to="activityUrl">
11
+                    <a>{{ activity.title }}</a>
12
+                </router-link>
11 13
             </h3>
12 14
             <div class="statistics">
13 15
                 阅读:{{ activity.read_num }} 丨 评论:{{ activity.comment_num }} 丨 点赞:{{ activity.star_num }}
@@ -52,6 +54,9 @@ export default {
52 54
                 return "已发布"
53 55
             }
54 56
         },
57
+        activityUrl: function() {
58
+            return "/activity?id=" + this.activity.id
59
+        },
55 60
         progress_percent: function() {
56 61
             if (this.activity.limit_num > 0) {
57 62
                 return (this.activity.join_num / this.activity.limit_num) * 100
@@ -71,7 +76,7 @@ export default {
71 76
             }
72 77
         },
73 78
         start_time: function() {
74
-            return parseTime(this.activity.start_time, "{y}-{m}-{d}")
79
+            return parseTime(this.activity.start_time, "{y}-{m}-{d} {h}-{i}")
75 80
         },
76 81
     },
77 82
 }

+ 8 - 3
src/scrm_pages/marketing_tool/components/unapproved_cell.vue ファイルの表示

@@ -13,8 +13,8 @@
13 13
                 审核未通过:{{ activity.reason }}
14 14
             </div>
15 15
             <div class="operation">
16
-                <el-button type="primary" size="small" icon="el-icon-edit-outline">编辑</el-button>
17
-                <el-button type="danger" size="small" icon="el-icon-delete">删除</el-button>
16
+                <el-button type="primary" size="small" icon="el-icon-edit-outline" @click="$router.push({ path: '/activity/modify', query: {id: activity.id} })">编辑</el-button>
17
+                <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteActivity">删除</el-button>
18 18
             </div>
19 19
         </div>
20 20
         <div class="activity-time-panel">
@@ -42,9 +42,14 @@ export default {
42 42
     },
43 43
     computed: {
44 44
         start_time: function() {
45
-            return parseTime(this.activity.start_time, "{y}-{m}-{d}")
45
+            return parseTime(this.activity.start_time, "{y}-{m}-{d} {h}:{i}")
46 46
         },
47 47
     },
48
+    methods: {
49
+        deleteActivity() {
50
+            this.$emit("delete")
51
+        }
52
+    }
48 53
 }
49 54
 </script>
50 55
 

+ 21 - 1
src/scrm_pages/members/cards.vue ファイルの表示

@@ -2,7 +2,11 @@
2 2
   <div class="main-contain">
3 3
     <div class="position">
4 4
       <bread-crumb :crumbs='crumbs'></bread-crumb>
5
-      <el-button  style="float:right;" type="primary" size="small" icon="el-icon-circle-plus-outline" @click="openCreate">添加会员卡</el-button>
5
+      <el-col :span="5" style="text-align: right;">
6
+        <el-button type="primary" size="small" icon="el-icon-circle-plus-outline" @click="openCreate">添加会员卡</el-button>
7
+        <el-button  type="primary" size="small" icon="el-icon-setting" @click="openRight">会员权益配置</el-button>
8
+      </el-col>
9
+      
6 10
     </div>
7 11
     <div class="app-container">
8 12
         <div class="filter-container" style="margin-top: 10px;margin-left: 5px " id="member-cards-box">
@@ -29,6 +33,8 @@
29 33
         <create-card-form ref="createCardForm" :cardsData="cardsData" ></create-card-form>
30 34
         <!--create-card-form 编辑会员卡-->
31 35
         <edit-card-form ref="editCardForm" :cardsData="cardsData" :cardIndex="cardIndex" :form="editFormData"></edit-card-form>
36
+        <!--create-right-form 编辑权益-->
37
+        <edit-card-right-form ref="editCardRightForm"  :form="rightData" ></edit-card-right-form>
32 38
     </div>
33 39
   </div>
34 40
 </template>
@@ -38,6 +44,7 @@
38 44
   import BreadCrumb from '../components/bread-crumb';
39 45
   import CreateCardForm from "./components/CreateCardForm";
40 46
   import EditCardForm from "./components/EditCardForm";
47
+  import EditCardRightForm from "./components/EditCardRightForm";
41 48
 
42 49
   export default {
43 50
     name: 'memberCardList',
@@ -45,6 +52,7 @@
45 52
       BreadCrumb,
46 53
       CreateCardForm,
47 54
       EditCardForm,
55
+      EditCardRightForm
48 56
     },
49 57
     data(){
50 58
       return{
@@ -53,6 +61,9 @@
53 61
           { path: false, name: '会员卡管理' }
54 62
         ],
55 63
         cardsData:[],
64
+        rightData:{
65
+          rights: "",
66
+        },
56 67
         editFormData:{
57 68
             background_type:1,
58 69
             background:"#409EFF",
@@ -72,6 +83,12 @@
72 83
         openCreate:function(){
73 84
           this.$refs.createCardForm.open();
74 85
         },
86
+        // updateRightData(right){
87
+        //   this.rightData.rights = right;
88
+        // },
89
+        openRight(){
90
+          this.$refs.editCardRightForm.open();
91
+        },
75 92
         openEdit(row, index) {
76 93
           for (const key in this.editFormData) {
77 94
             this.editFormData[key] = row[key];
@@ -106,6 +123,9 @@
106 123
                 var res = response.data;
107 124
                 if(res.state===1) {
108 125
                     this.cardsData = res.data.cards;
126
+                    if (res.data.right) {
127
+                      this.rightData.rights = res.data.right.rights;
128
+                    }
109 129
                 }
110 130
             }).catch(e=>{})
111 131
         }

+ 77 - 0
src/scrm_pages/members/components/EditCardRightForm.vue ファイルの表示

@@ -0,0 +1,77 @@
1
+<template>
2
+    <div id="edit-card-form-box">
3
+        <el-dialog title="会员协议配置" :visible.sync="editRightFormVisible" width="900px" id="edit-member-right-show" v-loading="submitLoading" :element-loading-text="loadingText">
4
+            <el-form ref="rightForm" :model="form" label-width="100px" id="edit-member-right-form">
5
+                <el-form-item label="会员权益:"  prop="rights">
6
+                    <el-input v-model="form.rights" type="textarea" rows='6' placeholder="" ></el-input>
7
+                </el-form-item>
8
+            </el-form>
9
+            
10
+            <div slot="footer" class="dialog-footer">
11
+                <el-button @click="editRightFormVisible = false">取消</el-button>
12
+                <el-button
13
+                type="primary"
14
+                @click="submitForm('rightForm')"
15
+                >保 存
16
+                </el-button>
17
+            </div>
18
+        </el-dialog>  
19
+    </div>
20
+</template>
21
+
22
+<script>
23
+import {EditRight} from "@/api/member/member";
24
+
25
+export default {
26
+    name:'EditCardRightForm',
27
+    props:{
28
+        form:{
29
+            rights:'',
30
+        },
31
+    },
32
+    data(){
33
+        return {
34
+            editRightFormVisible:false,
35
+            loadingText:'',
36
+            submitLoading:false,
37
+            
38
+        }
39
+    },
40
+    methods:{
41
+        open:function(){
42
+            this.editRightFormVisible = true;
43
+        },
44
+        resetForm:function(formName) {
45
+            if (typeof(this.$refs[formName]) !='undefined') {
46
+                this.$refs[formName].resetFields();
47
+            }
48
+        },
49
+        submitForm:function(formName){
50
+            this.$refs[formName].validate((valid) => {
51
+                if (valid) {
52
+                    this.loadingText = "正在保存...";
53
+                    this.submitLoading = true;
54
+                    EditRight(this.form).then(response=>{
55
+                        var res = response.data;
56
+                        if(res.state === 1) {
57
+                            // this.$emit('update-right', res.data.right.rights);
58
+                            this.editRightFormVisible = false;
59
+                            this.$message.success("编辑成功");
60
+                        }else {
61
+                            this.$message.error(res.msg);
62
+                        }
63
+                        this.submitLoading = false;
64
+                    }).catch(e=>{
65
+                        this.submitLoading = false;
66
+                    });
67
+                } else {
68
+                    return false;
69
+                }
70
+            });
71
+        },
72
+    },
73
+    computed: {
74
+    
75
+    },
76
+}
77
+</script>

+ 77 - 10
src/scrm_pages/weixinmp/authorization.vue ファイルの表示

@@ -2,6 +2,7 @@
2 2
   <div class="main-contain">
3 3
     <div class="position">
4 4
       <bread-crumb :crumbs="crumbs"></bread-crumb>
5
+      <el-button  style="float:right;" type="primary" size="small" :disabled="resetSubmit" icon="el-icon-refresh" @click="resetPage">刷新</el-button>
5 6
     </div>
6 7
     <div class="app-container" id="winxin-auth-box">
7 8
       <div class="filter-container" style="margin-top: 10px;margin-left: 5px ">
@@ -9,10 +10,10 @@
9 10
           <div class="bind-title-box">
10 11
             <span class="bind-title">您已绑定公众号,如需更换绑定公众号,请点击下面按钮</span>
11 12
           </div>
12
-          <el-button type="warning">更换绑定公众号</el-button>
13
+          <el-button type="warning" @click="getAuthUrl" >更换绑定公众号</el-button>
13 14
           <div class="bind-massage-box">
14 15
             <span>
15
-              授权公众号:{{authData.authorizer_nick_name}},类型:{{mpTypeName}},
16
+              授权公众号:{{authData.authorizer_nick_name}}
16 17
               <!--授权方公众号类型,0代表订阅号,1代表由历史老帐号升级后的订阅号,2代表服务号-->
17 18
               <!-- authorizer_service_type_info -->
18 19
             </span>
@@ -22,7 +23,7 @@
22 23
           <div class="bind-title-box">
23 24
             <span class="bind-title">您尚未绑定公众号</span>
24 25
           </div>
25
-          <el-button type="warning">已有公众号,立刻绑定</el-button>
26
+          <el-button type="warning" @click="getAuthUrl" >已有公众号,立刻绑定</el-button>
26 27
           <div class="bind-massage-box">
27 28
             <span>
28 29
               如果还没有公众号,需要先在微信公众号平台进行申请。 去
@@ -54,19 +55,33 @@
54 55
       <div style="height:20px">&nbsp;</div>
55 56
       <div class="dataTitle title-12">如何取消给酷医云的授权?</div>
56 57
       <div class="dataBody">
57
-        <p>公众号取消授权,进入微信后台,点击“+添加功能插件”,进入“授权管理”,就可以看到酷医云的授权,并且解除授权了。</p>
58
+        <p>公众号取消授权,进入微信后台,点击“设置-公众号设置-授权管理”,就可以看到酷医云的授权,并且解除授权了。</p>
58 59
       </div>
59 60
     </div>
61
+    <el-dialog
62
+      title="授权二维码"
63
+      :visible.sync="centerDialogVisible"
64
+      width="30%"
65
+      center>
66
+      <div style="text-align:center;">
67
+        <div><span>请用微信扫描下方二维码</span></div>
68
+        <div id="mpwechat-auth-qrcode" ref="qrcode" ></div>
69
+        <div><span>在手机完成授权后,点击右上角的刷新按钮</span></div>
70
+      </div>
71
+    </el-dialog>
72
+
60 73
   </div>
61 74
 </template>
62 75
 
63 76
 <script>
64 77
 import BreadCrumb from "../components/bread-crumb";
65
-
78
+import QRCode from 'qrcodejs2'  // 引入qrcode
79
+import {GetAuthorizationInfo,GetAuthUrl} from "@/api/mpwechat/mpwechat";
66 80
 export default {
67 81
   name: "authorization",
68 82
   components: {
69
-    BreadCrumb
83
+    BreadCrumb,
84
+    QRCode,
70 85
   },
71 86
   data() {
72 87
     return {
@@ -74,7 +89,9 @@ export default {
74 89
         { path: false, name: "系统设置" },
75 90
         { path: false, name: "公众号授权" }
76 91
       ],
77
-
92
+      showAuthButton:true,
93
+      centerDialogVisible:false,
94
+      resetSubmit:false,
78 95
       authData: {
79 96
         id: 0,
80 97
         user_org_id: 0,
@@ -93,12 +110,58 @@ export default {
93 110
         authorizer_qrcode_url: "",
94 111
         created_time: "",
95 112
         updated_time: "",
96
-        authorizer_status: 1
113
+        authorizer_status: 0
97 114
       }
98 115
     };
99 116
   },
100
-  methods: {},
101
-  created() {},
117
+  methods: {
118
+    getAuthUrl:function(){
119
+      // this.showAuthButton = false;
120
+      GetAuthUrl().then(response=>{
121
+        var res =  response.data;
122
+        if (res.state===1) {
123
+          var url = res.data.url;
124
+          this.centerDialogVisible = true;
125
+          this.$nextTick (function () {
126
+            this.qrcode(url);
127
+          })
128
+        }else {
129
+          this.$message.error(res.msg);
130
+        }
131
+      }).catch(e=>{
132
+        
133
+        // this.showAuthButton = true;
134
+      });
135
+    },
136
+    qrcode(url) {
137
+      document.getElementById('mpwechat-auth-qrcode').innerHTML = ''
138
+      let qrcode = new QRCode('mpwechat-auth-qrcode', {
139
+        width: 150,  
140
+        height: 150,
141
+        text: url,
142
+        colorDark : "#000",
143
+        colorLight : "#fff",
144
+      })
145
+    },
146
+    resetPage(){
147
+      this.GetAuthorizationInfo();
148
+    },
149
+    GetAuthorizationInfo:function(){
150
+      GetAuthorizationInfo().then(response=>{
151
+        var res =  response.data;
152
+        if(res.state===1) {
153
+          if(res.data.authorization) {
154
+            this.authData = res.data.authorization;
155
+          }
156
+        }else {
157
+          this.$message.error(res.msg);
158
+        }
159
+      }).catch(e=>{});
160
+    },
161
+  },
162
+  created() {
163
+    this.GetAuthorizationInfo();
164
+  },
102 165
   computed:{
103 166
     mpTypeName:function(){
104 167
       return 'xx';
@@ -166,6 +229,10 @@ export default {
166 229
   font-size: 14px;
167 230
   line-height: 18px;
168 231
 }
232
+#mpwechat-auth-qrcode{
233
+  width: 150px;
234
+  margin: 5px auto;
235
+}
169 236
 /*.app-container .cell.clearfix .time ul li {*/
170 237
 /*float: left;*/
171 238
 /*list-style: none;*/

+ 101 - 0
src/scrm_pages/weixinmp/components/CreateKWReplyForm.vue ファイルの表示

@@ -0,0 +1,101 @@
1
+<template>
2
+    <div id="create-kw-reply-form-box">
3
+        <el-dialog title="添加关键词回复" :visible.sync="createKWReplyFormVisible" width="700px" >
4
+            <el-form ref="replyForm" :rules="replyRules" :model="form" label-width="90px">
5
+                <el-form-item label="规则名称:" required prop="message_regular_name">
6
+                    <el-input v-model="form.message_regular_name"></el-input>
7
+                </el-form-item>
8
+                <el-form-item label="模式:" required prop="message_key_type">
9
+                    <el-radio-group v-model="form.message_key_type">
10
+                        <el-radio :label="item.id" :value="item.id" v-for="(item, index) in keyTypeOptions" :key="index" >{{item.name}}</el-radio>
11
+                    </el-radio-group>
12
+                </el-form-item>
13
+                <el-form-item label="关键字:" required prop="message_key_name">
14
+                    <el-input v-model="form.message_key_name"></el-input>
15
+                </el-form-item>
16
+                <el-form-item label="回复内容:" required prop="message_content">
17
+                    <el-input v-model="form.message_content" type="textarea" rows="4"></el-input>
18
+                </el-form-item>
19
+            </el-form>
20
+            <div slot="footer" class="dialog-footer">
21
+                <el-button @click="createKWReplyFormVisible = false">取消</el-button>
22
+                <el-button
23
+                type="primary"
24
+                @click="submitForm('replyForm')"
25
+                >保 存
26
+                </el-button>
27
+            </div>
28
+        </el-dialog>  
29
+    </div>
30
+</template>
31
+
32
+<script>
33
+import {CreateKeyWordReply} from "@/api/mpwechat/mpreply";
34
+
35
+export default {
36
+    name:'CreateReplyForm',
37
+    props:{
38
+        replysData:{
39
+            type: Array,
40
+            default: function () {
41
+                return [];
42
+            }
43
+        },
44
+    },
45
+    data(){
46
+        return {
47
+            createKWReplyFormVisible:false,
48
+            keyTypeOptions:[
49
+                {id:1, name:'半匹配'},
50
+                {id:2, name:'全匹配'},
51
+            ],
52
+            replyRules: {
53
+                message_regular_name: [{required: true, message: "请填写规则名称",},],
54
+                message_key_type: [{required: true, message: "请选择模式",},],
55
+                message_key_name: [{required: true, message: "请填写关键字",},],
56
+                message_content: [{required: true, message: "请填写回复内容",},],
57
+            },
58
+            form:{
59
+                message_regular_name:'',
60
+                message_key_type:1,
61
+                message_key_name:'',
62
+                message_content:'',
63
+            },
64
+            
65
+        }
66
+    },
67
+    methods:{
68
+        open:function(){
69
+            this.resetForm("replyForm");
70
+            this.createKWReplyFormVisible = true;
71
+        },
72
+        resetForm(formName) {
73
+            if (typeof(this.$refs[formName]) !='undefined') {
74
+                this.$refs[formName].resetFields();
75
+            }
76
+        },
77
+        submitForm(formName){
78
+            this.$refs[formName].validate((valid) => {
79
+                if (valid) {
80
+                    CreateKeyWordReply(this.form).then(response=>{
81
+                        var res = response.data;
82
+                        if(res.state === 1) {
83
+                            var message = res.data.message;
84
+                            this.replysData.unshift(message);
85
+                            this.resetForm("replyForm");
86
+                            this.createKWReplyFormVisible = false;
87
+                            this.$message.success("添加成功");
88
+                        }else {
89
+                            this.$message.error(res.msg);
90
+                        }
91
+                    }).catch(e=>{});
92
+
93
+                } else {
94
+                    return false;
95
+                }
96
+            });
97
+        },
98
+    }
99
+}
100
+</script>
101
+

+ 105 - 0
src/scrm_pages/weixinmp/components/EditKWReplyForm.vue ファイルの表示

@@ -0,0 +1,105 @@
1
+<template>
2
+    <div id="edit-kw-reply-form-box">
3
+        <el-dialog title="编辑关键词回复" :visible.sync="editKWReplyFormVisible" width="700px" >
4
+            <el-form ref="replyForm" :rules="replyRules" :model="form" label-width="90px">
5
+                <el-form-item label="规则名称:" required prop="message_regular_name">
6
+                    <el-input v-model="form.message_regular_name"></el-input>
7
+                </el-form-item>
8
+                <el-form-item label="模式:" required prop="message_key_type">
9
+                    <el-radio-group v-model="form.message_key_type">
10
+                        <el-radio :label="item.id" :value="item.id" v-for="(item, index) in keyTypeOptions" :key="index" >{{item.name}}</el-radio>
11
+                    </el-radio-group>
12
+                </el-form-item>
13
+                <el-form-item label="关键字:" required prop="message_key_name">
14
+                    <el-input v-model="form.message_key_name"></el-input>
15
+                </el-form-item>
16
+                <el-form-item label="回复内容:" required prop="message_content">
17
+                    <el-input v-model="form.message_content" type="textarea" rows="4"></el-input>
18
+                </el-form-item>
19
+            </el-form>
20
+            <div slot="footer" class="dialog-footer">
21
+                <el-button @click="editKWReplyFormVisible = false">取消</el-button>
22
+                <el-button
23
+                type="primary"
24
+                @click="submitForm('replyForm')"
25
+                >保 存
26
+                </el-button>
27
+            </div>
28
+        </el-dialog>  
29
+    </div>
30
+</template>
31
+
32
+<script>
33
+import {EditKeyWordReply} from "@/api/mpwechat/mpreply";
34
+
35
+export default {
36
+    name:'EditReplyForm',
37
+    props:{
38
+        replysData:{
39
+            type: Array,
40
+            default: function () {
41
+                return [];
42
+            }
43
+        },
44
+        replyIndex:{
45
+            type:Number,
46
+            default:-1,
47
+        },
48
+        form:{
49
+            id:0,
50
+            message_regular_name:'',
51
+            message_key_type:1,
52
+            message_key_name:'',
53
+            message_content:'',
54
+        },
55
+    },
56
+    data(){
57
+        return {
58
+            editKWReplyFormVisible:false,
59
+            keyTypeOptions:[
60
+                {id:1, name:'半匹配'},
61
+                {id:2, name:'全匹配'},
62
+            ],
63
+            replyRules: {
64
+                message_regular_name: [{required: true, message: "请填写规则名称",},],
65
+                message_key_type: [{required: true, message: "请选择模式",},],
66
+                message_key_name: [{required: true, message: "请填写关键字",},],
67
+                message_content: [{required: true, message: "请填写回复内容",},],
68
+            },
69
+            
70
+        }
71
+    },
72
+    methods:{
73
+        open:function(){
74
+            this.editKWReplyFormVisible = true;
75
+        },
76
+        resetForm(formName) {
77
+            if (typeof(this.$refs[formName]) !='undefined') {
78
+                this.$refs[formName].resetFields();
79
+            }
80
+        },
81
+        submitForm(formName){
82
+            this.$refs[formName].validate((valid) => {
83
+                if (valid) {
84
+                    EditKeyWordReply(this.form.id, this.form).then(response=>{
85
+                        var res = response.data;
86
+                        if(res.state === 1) {
87
+                            var message = res.data.message;
88
+                            this.replysData.splice(this.replyIndex, 1, message);
89
+                            this.resetForm("replyForm");
90
+                            this.editKWReplyFormVisible = false;
91
+                            this.$message.success("编辑成功");
92
+                        }else {
93
+                            this.$message.error(res.msg);
94
+                        }
95
+                    }).catch(e=>{});
96
+
97
+                } else {
98
+                    return false;
99
+                }
100
+            });
101
+        },
102
+    }
103
+}
104
+</script>
105
+

+ 30 - 0
src/scrm_pages/weixinmp/components/replyNav.vue ファイルの表示

@@ -0,0 +1,30 @@
1
+<template>
2
+    <el-tabs v-model="tabActiveName" @tab-click="handleTabClick" style="margin-bottom:10px">
3
+        <el-tab-pane label="关键词回复" name="keyword"></el-tab-pane>
4
+        <el-tab-pane label="关注后回复" name="subscribe"></el-tab-pane>
5
+    </el-tabs>
6
+</template>
7
+<script>
8
+export default {
9
+    props:{
10
+        activeName:{
11
+            type:String,
12
+            default: 'subscribe'
13
+        }
14
+    },
15
+    data(){
16
+        return{
17
+            tabActiveName:'subscribe',
18
+        }
19
+    }, 
20
+    methods:{
21
+        handleTabClick(tab, event) {
22
+            this.$router.push({ path: "/weixinmp/reply/"+this.tabActiveName });
23
+        }
24
+    },
25
+    created(){
26
+        this.tabActiveName = this.activeName
27
+    },
28
+}
29
+</script>
30
+

+ 234 - 0
src/scrm_pages/weixinmp/keywordreply.vue ファイルの表示

@@ -0,0 +1,234 @@
1
+<template>
2
+  <div class="main-contain">
3
+    <div class="position">
4
+      <bread-crumb :crumbs='crumbs'></bread-crumb>
5
+      <el-button  style="float:right;" type="primary" size="small" icon="el-icon-circle-plus-outline" @click="openCreate">添加回复</el-button>
6
+    </div>
7
+    <div class="app-container">
8
+        <reply-nav activeName="keyword"></reply-nav>
9
+        <div style="margin-bottom: 10px">
10
+            <el-row :gutter="24">
11
+                <el-col :span="8">
12
+                    <el-input style="width: 300px" v-model="listQuery.search" placeholder="请输入您需要搜索的内容"></el-input>
13
+                    <el-button type="primary"  icon="el-icon-search" @click="changeKey">搜索</el-button>
14
+                </el-col>
15
+            </el-row>
16
+        </div>
17
+        <div class="filter-container" style="margin-top: 10px;margin-left: 5px">
18
+            <el-checkbox style="width: 30px" @change="changeCheck" v-model="checkAllStatus">全选</el-checkbox>
19
+            <el-button size="small" icon="el-icon-delete" @click="openDeleteReplys">批量删除</el-button>
20
+        </div>
21
+        <el-table ref="multipleTable"  @selection-change="handleSelectionChange"  :header-cell-style="{ backgroundColor: 'rgb(245, 247, 250)'}" :data="messagesData" border fit highlight-current-row  style="width: 100%;margin-top: 10px;">
22
+            <el-table-column
23
+                align="center"
24
+                type="selection"
25
+                width="55">
26
+             </el-table-column>
27
+            <el-table-column label="关键词" align="center">
28
+                <template slot-scope="scope">
29
+                    {{scope.row.message_key_name}}
30
+                </template>
31
+            </el-table-column>
32
+            <el-table-column label="回复内容" align="center">
33
+                <template slot-scope="scope">
34
+                <span>{{scope.row.message_content}}</span>
35
+                </template>
36
+            </el-table-column>
37
+            <el-table-column label="模式" align="center">
38
+                <template slot-scope="scope">
39
+                <span>{{keyTypeName(scope.row.message_key_type)}}</span>
40
+                </template>
41
+            </el-table-column>
42
+            <el-table-column label="操作" align="center">
43
+                <template slot-scope="scope">
44
+                    <el-tooltip class="item" effect="dark" content="编辑" placement="top">
45
+                        <el-button size="mini" type="primary" icon="el-icon-edit-outline" @click="openEdit(scope.row, scope.$index)" ></el-button>
46
+                    </el-tooltip>
47
+                    <el-tooltip class="item" effect="dark" content="删除" placement="top">
48
+                        <el-button size="mini" type="danger" icon="el-icon-delete" @click="openDelete(scope.row, scope.$index)" ></el-button>
49
+                    </el-tooltip>
50
+                </template>
51
+            </el-table-column>
52
+        </el-table>
53
+        <el-pagination
54
+            @size-change="handleSizeChange"
55
+            @current-change="handleCurrentChange"
56
+            :page-sizes="[10,20,50,100]"
57
+            :page-size="10"
58
+            background
59
+            style="margin-top:20px;"
60
+            align="right"
61
+            layout="total, sizes, prev, pager, next, jumper"
62
+            :total="total">
63
+        </el-pagination>
64
+        <!--添加-->
65
+        <create-k-w-reply-form ref="createKWReplyForm" :replysData="messagesData" ></create-k-w-reply-form>
66
+        <!--编辑-->
67
+        <edit-k-w-reply-form ref="editKWReplyForm" :replysData="messagesData" :replyIndex="replyIndex" :form="editForm"></edit-k-w-reply-form>
68
+    </div>
69
+  </div>
70
+</template>
71
+
72
+<script>
73
+  import {GetKeyWordReplys,DeleteReplys} from "@/api/mpwechat/mpreply";
74
+  import BreadCrumb from '../components/bread-crumb';
75
+  import CreateKWReplyForm from './components/CreateKWReplyForm';
76
+  import EditKWReplyForm from './components/EditKWReplyForm';
77
+import replyNav from "./components/replyNav";
78
+
79
+  export default {
80
+    name: 'keywordreply',
81
+    components:{
82
+      BreadCrumb,
83
+      replyNav,
84
+      CreateKWReplyForm,
85
+      EditKWReplyForm,
86
+    },
87
+    data(){
88
+      return{
89
+        crumbs: [
90
+        { path: false, name: "系统设置" },
91
+        { path: false, name: "关键词回复" }
92
+        ],
93
+        total:0,
94
+        listQuery:{
95
+            page:1,
96
+            limit:10,
97
+            search:'',
98
+        },
99
+        checkAllStatus:false,
100
+        selectedReplys:[],
101
+        messagesData:[],
102
+        replyIndex:-1,
103
+        editForm:{
104
+            id:0,
105
+            message_regular_name:'',
106
+            message_key_type:1,
107
+            message_key_name:'',
108
+            message_content:'',
109
+        },
110
+      }
111
+    },
112
+    methods:{
113
+        openCreate:function(){
114
+          this.$refs.createKWReplyForm.open();
115
+        },
116
+        openEdit:function(row,index){
117
+            this.replyIndex = index;
118
+            for (const key in this.editForm) {
119
+              this.editForm[key] = row[key];
120
+            }
121
+            this.$refs.editKWReplyForm.open();
122
+        },
123
+        openDeleteReplys:function(){
124
+          if (this.selectedReplys.length==0) {
125
+            this.$message.error("请选择要删除的回复");
126
+            return false;
127
+          }
128
+
129
+          this.$confirm('确认要删除所选的回复吗?<br>删除后,回复将无法恢复', '删除提示', {
130
+            dangerouslyUseHTMLString:true,
131
+            confirmButtonText: '确定',
132
+            cancelButtonText: '取消',
133
+            type: 'warning'
134
+          }).then(() => {
135
+            var ids = [];
136
+            var idMap = {};
137
+            for (const index in this.selectedReplys) {
138
+              ids.push(this.selectedReplys[index].id);
139
+              idMap[this.selectedReplys[index].id] = this.selectedReplys[index].id;
140
+            }
141
+            DeleteReplys({ids:ids}).then(response=>{
142
+              var res = response.data;
143
+              if (res.state === 1) {
144
+                var dataLength = this.messagesData.length;
145
+                for (let index = dataLength-1; index >= 0; index--) {
146
+                  if(this.messagesData[index].id in idMap) {
147
+                    this.messagesData.splice(index, 1);
148
+                  }                  
149
+                }
150
+                this.$message.success("删除成功");
151
+              }else {
152
+                this.$message.error(res.msg);
153
+              }
154
+            }).catch(e=>{});
155
+          }).catch(() => {
156
+            return false        
157
+          });
158
+        },
159
+        openDelete:function(row,index){
160
+          this.$confirm('确认要删除该回复吗?<br>删除后,该回复将无法恢复', '删除提示', {
161
+            dangerouslyUseHTMLString:true,
162
+            confirmButtonText: '确定',
163
+            cancelButtonText: '取消',
164
+            type: 'warning'
165
+          }).then(() => {
166
+            var ids = [];
167
+            ids.push(row.id);
168
+            DeleteReplys({ids:ids}).then(response=>{
169
+              var res = response.data;
170
+              if (res.state === 1) {
171
+                this.messagesData.splice(index, 1);
172
+                this.$message.success("删除成功");
173
+              }else {
174
+                this.$message.error(res.msg);
175
+              }
176
+            }).catch(e=>{});
177
+          }).catch(() => {
178
+            return false        
179
+          });
180
+        },
181
+        changeCheck:function(){
182
+          this.$refs.multipleTable.clearSelection();
183
+          if (this.checkAllStatus) {
184
+            this.$refs.multipleTable.toggleAllSelection();
185
+          }
186
+        },
187
+        handleSelectionChange:function (val) {
188
+          this.selectedReplys = val;
189
+        },
190
+        handleSizeChange(limit) {
191
+            this.listQuery.limit = limit;
192
+            this.GetKeyWordReplys();
193
+        },
194
+        handleCurrentChange(page) {
195
+            this.listQuery.page = page;
196
+            this.GetKeyWordReplys();
197
+        },
198
+        changeKey(){
199
+            this.GetKeyWordReplys();
200
+        },
201
+        keyTypeName:function(type){
202
+          return type == 1?'半匹配':'全匹配';
203
+        },
204
+        GetKeyWordReplys(){
205
+            GetKeyWordReplys(this.listQuery).then(response=>{
206
+                var res = response.data;
207
+                if(res.state===1) {
208
+                    this.messagesData = res.data.messages;
209
+                    this.total = res.data.total;
210
+                }
211
+            }).catch(e=>{})
212
+        }
213
+    },
214
+    computed:{
215
+    },
216
+    created(){
217
+        this.GetKeyWordReplys();
218
+    }
219
+  }
220
+</script>
221
+
222
+<style scoped>
223
+  /*.app-container .cell.clearfix .time ul li {*/
224
+    /*float: left;*/
225
+    /*list-style: none;*/
226
+    /*cursor: pointer;*/
227
+    /*padding: 6px 20px;*/
228
+    /*color: #606266;*/
229
+    /*border-radius: 4px;*/
230
+    /*margin: 0 8px 0 0;*/
231
+    /*font-size: 14px;*/
232
+    /*text-align: center;*/
233
+  /*}*/
234
+</style>

File diff suppressed because it is too large
+ 1159 - 0
src/scrm_pages/weixinmp/menus.vue


+ 117 - 0
src/scrm_pages/weixinmp/subscribereply.vue ファイルの表示

@@ -0,0 +1,117 @@
1
+<template>
2
+  <div class="main-contain">
3
+    <div class="position">
4
+      <bread-crumb :crumbs="crumbs"></bread-crumb>
5
+    </div>
6
+    <div class="app-container" id="winxin-subscribe-replu-box">
7
+      <reply-nav activeName="subscribe"></reply-nav>
8
+      <el-form ref="form" :model="form" >
9
+        <el-form-item label="">
10
+          <el-input type="textarea" v-model="form.message_content" rows='5'></el-input>
11
+        </el-form-item>
12
+        <el-form-item>
13
+          <!-- <el-col :span="24" style="text-align: right;"> -->
14
+            <el-button type="primary" align="right" @click="saveReply">保存</el-button>
15
+          <!-- </el-col> -->
16
+        </el-form-item>
17
+      </el-form>
18
+    </div>
19
+  </div>
20
+</template>
21
+
22
+<script>
23
+import BreadCrumb from "../components/bread-crumb";
24
+import replyNav from "./components/replyNav";
25
+import {GetAuthorizationInfo} from "@/api/mpwechat/mpwechat";
26
+import {GetSubscribeRplay,SaveSubscribeRplay} from "@/api/mpwechat/mpreply";
27
+
28
+export default {
29
+  name: "subscribereply",
30
+  components: {
31
+    BreadCrumb,
32
+    replyNav,
33
+  },
34
+  data() {
35
+    return {
36
+      crumbs: [
37
+        { path: false, name: "系统设置" },
38
+        { path: false, name: "关注后回复" }
39
+      ],
40
+      initReply:false,
41
+      form:{
42
+        'message_content':'',
43
+      },
44
+    };
45
+  },
46
+  methods: {
47
+    GetAuthorizationInfo:function(){
48
+      GetAuthorizationInfo().then(response=>{
49
+        var res =  response.data;
50
+        if(res.state===1) {
51
+          if(res.data.authorization) {
52
+            this.authData = res.data.authorization;
53
+            if (this.authData.authorizer_status != 1) {
54
+              this.$message.error("公众号未授权");
55
+              this.$router.push({path:"/weixinmp/authorization"})
56
+              return false;
57
+            }else if (this.authData.authorizer_verify_type_info>=0 || this.authData.authorizer_service_type_info==2) {
58
+              this.initReply = true;
59
+            }
60
+          }else {
61
+              this.$message.error("公众号未授权");
62
+              this.$router.push({path:"/weixinmp/authorization"})
63
+          }
64
+        }else {
65
+          this.$message.error(res.msg);
66
+        }
67
+      }).catch(e=>{});
68
+    },
69
+    GetSubscribeRplay:function(){
70
+      GetSubscribeRplay().then(response=>{
71
+        var res = response.data;
72
+        if (res.state==1) {
73
+          if (res.data.message) {
74
+            this.form.message_content = res.data.message.message_content;
75
+          }
76
+        }else {
77
+          this.$message.error(res.msg);
78
+        }
79
+      }).catch(e=>{});
80
+    },
81
+    saveReply:function(){
82
+      SaveSubscribeRplay(this.form).then(response=>{
83
+        var res = response.data;
84
+        if (res.state === 1) {
85
+          this.$message.success('保存成功');
86
+        }else {
87
+          this.$message.error(res.msg);
88
+        }
89
+      }).catch(e=>{});
90
+    }
91
+  },
92
+  created() {
93
+    this.GetAuthorizationInfo();
94
+  },
95
+  computed:{
96
+  },
97
+  watch:{
98
+    'initReply':function(){
99
+      this.GetSubscribeRplay();
100
+    }
101
+  },
102
+};
103
+</script>
104
+
105
+<style scoped>
106
+/*.app-container .cell.clearfix .time ul li {*/
107
+/*float: left;*/
108
+/*list-style: none;*/
109
+/*cursor: pointer;*/
110
+/*padding: 6px 20px;*/
111
+/*color: #606266;*/
112
+/*border-radius: 4px;*/
113
+/*margin: 0 8px 0 0;*/
114
+/*font-size: 14px;*/
115
+/*text-align: center;*/
116
+/*}*/
117
+</style>

+ 9 - 9
src/xt_permission.js ファイルの表示

@@ -5,19 +5,19 @@ import 'nprogress/nprogress.css'// progress bar style
5 5
 
6 6
 NProgress.configure({ showSpinner: false })// NProgress Configuration
7 7
 
8
-const loginWhiteList = ['/token/verify', '/401', '/404'] // 登录验证白名单
8
+const loginWhiteList = ['/token/verify', '/401', '/404', "/activity/preview"] // 登录验证白名单
9 9
 const permissionWhiteList = loginWhiteList.concat(['/']) // 权限验证白名单
10 10
 
11 11
 router.beforeEach((to, from, next) => {
12 12
   // 线上注释
13
-  if (store.getters.permission_routers === undefined) {
14
-    store.dispatch('xt_GenerateRoutes', []).then(() => {
15
-      next()
16
-    })
17
-  } else {
18
-    next()
19
-  }
20
-  return
13
+  // if (store.getters.permission_routers === undefined) {
14
+  //   store.dispatch('xt_GenerateRoutes', []).then(() => {
15
+  //     next()
16
+  //   })
17
+  // } else {
18
+  //   next()
19
+  // }
20
+  // return
21 21
   // 线上注释
22 22
 
23 23
   NProgress.start()