aamin 2 роки тому
батько
коміт
4f789b8c96

+ 384 - 6
houtai/package-lock.json

@@ -18,6 +18,8 @@
         "@types/react-dom": "^18.0.8",
         "antd": "^5.0.4",
         "axios": "^1.1.3",
+        "braft-editor": "^2.3.9",
+        "braft-utils": "^3.0.12",
         "dayjs": "^1.11.7",
         "echarts": "^5.4.0",
         "file-saver": "^2.0.5",
@@ -5311,6 +5313,88 @@
         "node": ">=8"
       }
     },
+    "node_modules/braft-convert": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/braft-convert/-/braft-convert-2.3.0.tgz",
+      "integrity": "sha512-5km+dLHk8iYDv2iEYDrDQ2ld/ZoUx66QLql0qdm5PqZEcNXc8dBHGLORfzeu3iMw1jLeAiHxtdY5+ypuIhczVg==",
+      "dependencies": {
+        "draft-convert": "^2.0.0",
+        "draft-js": "^0.10.3"
+      },
+      "peerDependencies": {
+        "react": "^16.0.0"
+      }
+    },
+    "node_modules/braft-convert/node_modules/draft-convert": {
+      "version": "2.1.13",
+      "resolved": "https://registry.npmmirror.com/draft-convert/-/draft-convert-2.1.13.tgz",
+      "integrity": "sha512-/h/n4JCfyO8aWby7wKBkccHdsuVbbDyHWXi/B3Zf2pN++lN1lDOIVt5ulXCcbH2Y5YJEFzMJw/YGfN+R0axxxg==",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5",
+        "immutable": "~3.7.4",
+        "invariant": "^2.2.1"
+      },
+      "peerDependencies": {
+        "draft-js": ">=0.7.0",
+        "react": "^15.0.2 || ^16.0.0-rc || ^16.0.0 || ^17.0.0 || ^18.0.0",
+        "react-dom": "^15.0.2 || ^16.0.0-rc || ^16.0.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
+    "node_modules/braft-editor": {
+      "version": "2.3.9",
+      "resolved": "https://registry.npmmirror.com/braft-editor/-/braft-editor-2.3.9.tgz",
+      "integrity": "sha512-mqdPk/zI2dhFK8tW/A4Qj/AkkARLh5L/niNw+iif5wFqb6zh15rMlrShgz1nWO/QXyAKr8XtDgxiBbR0zWwtRg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "braft-convert": "^2.3.0",
+        "braft-finder": "^0.0.19",
+        "braft-utils": "^3.0.8",
+        "draft-convert": "^2.0.0",
+        "draft-js": "^0.10.3",
+        "draft-js-multidecorators": "^1.0.0",
+        "draftjs-utils": "^0.9.4",
+        "immutable": "~3.7.4"
+      },
+      "peerDependencies": {
+        "react": "^15.0.2|| ^16.0.0-rc || ^16.0.0",
+        "react-dom": "^15.0.2|| ^16.0.0-rc || ^16.0.0"
+      }
+    },
+    "node_modules/braft-editor/node_modules/braft-finder": {
+      "version": "0.0.19",
+      "resolved": "https://registry.npmmirror.com/braft-finder/-/braft-finder-0.0.19.tgz",
+      "integrity": "sha512-0kzI6/KbomJJhYX1hpjn4edCKhblyUyWdUrsgBmOrwy0vrj+pPkm69+Uf8Uj6KGAULM6LF0ooC++p7fqUGgFHw==",
+      "peerDependencies": {
+        "react": "^16.4.1",
+        "react-dom": "^16.4.1"
+      }
+    },
+    "node_modules/braft-editor/node_modules/draft-convert": {
+      "version": "2.1.13",
+      "resolved": "https://registry.npmmirror.com/draft-convert/-/draft-convert-2.1.13.tgz",
+      "integrity": "sha512-/h/n4JCfyO8aWby7wKBkccHdsuVbbDyHWXi/B3Zf2pN++lN1lDOIVt5ulXCcbH2Y5YJEFzMJw/YGfN+R0axxxg==",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5",
+        "immutable": "~3.7.4",
+        "invariant": "^2.2.1"
+      },
+      "peerDependencies": {
+        "draft-js": ">=0.7.0",
+        "react": "^15.0.2 || ^16.0.0-rc || ^16.0.0 || ^17.0.0 || ^18.0.0",
+        "react-dom": "^15.0.2 || ^16.0.0-rc || ^16.0.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
+    "node_modules/braft-utils": {
+      "version": "3.0.12",
+      "resolved": "https://registry.npmmirror.com/braft-utils/-/braft-utils-3.0.12.tgz",
+      "integrity": "sha512-O2cKysURNC4HSEMKgNmQ2RluwcrxvYrztlEmyPN5SzktiNX3vaLFQoo0Ez3PlIhvjaGrIBSIT2Oyh2N6mn6TFg==",
+      "peerDependencies": {
+        "braft-convert": "^2.1.4",
+        "draft-js": "^0.10.5",
+        "draftjs-utils": "^0.9.4",
+        "immutable": "~3.7.4"
+      }
+    },
     "node_modules/browser-process-hrtime": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
@@ -6641,6 +6725,37 @@
       "resolved": "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
       "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
     },
+    "node_modules/draft-js": {
+      "version": "0.10.5",
+      "resolved": "https://registry.npmmirror.com/draft-js/-/draft-js-0.10.5.tgz",
+      "integrity": "sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg==",
+      "dependencies": {
+        "fbjs": "^0.8.15",
+        "immutable": "~3.7.4",
+        "object-assign": "^4.1.0"
+      },
+      "peerDependencies": {
+        "react": "^0.14.0 || ^15.0.0-rc || ^16.0.0-rc || ^16.0.0",
+        "react-dom": "^0.14.0 || ^15.0.0-rc || ^16.0.0-rc || ^16.0.0"
+      }
+    },
+    "node_modules/draft-js-multidecorators": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/draft-js-multidecorators/-/draft-js-multidecorators-1.0.0.tgz",
+      "integrity": "sha512-7qdy+YQol5iq38AoEerhgSJWhCzxvZLn1x5ODfUlGfWlg0SrZ9AXJbaxHVIjdSIZNrbVIm+WANujNxMqCmDSZQ==",
+      "dependencies": {
+        "immutable": "*"
+      }
+    },
+    "node_modules/draftjs-utils": {
+      "version": "0.9.4",
+      "resolved": "https://registry.npmmirror.com/draftjs-utils/-/draftjs-utils-0.9.4.tgz",
+      "integrity": "sha512-KYjABSbGpJrwrwmxVj5UhfV37MF/p0QRxKIyL+/+QOaJ8J9z1FBKxkblThbpR0nJi9lxPQWGg+gh+v0dAsSCCg==",
+      "peerDependencies": {
+        "draft-js": "^0.10.x",
+        "immutable": "3.x.x || 4.x.x"
+      }
+    },
     "node_modules/duplexer": {
       "version": "0.1.2",
       "resolved": "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz",
@@ -6713,6 +6828,14 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/encoding": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+      "dependencies": {
+        "iconv-lite": "^0.6.2"
+      }
+    },
     "node_modules/enhanced-resolve": {
       "version": "5.10.0",
       "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
@@ -7758,6 +7881,34 @@
         "bser": "2.1.1"
       }
     },
+    "node_modules/fbjs": {
+      "version": "0.8.18",
+      "resolved": "https://registry.npmmirror.com/fbjs/-/fbjs-0.8.18.tgz",
+      "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==",
+      "dependencies": {
+        "core-js": "^1.0.0",
+        "isomorphic-fetch": "^2.1.1",
+        "loose-envify": "^1.0.0",
+        "object-assign": "^4.1.0",
+        "promise": "^7.1.1",
+        "setimmediate": "^1.0.5",
+        "ua-parser-js": "^0.7.30"
+      }
+    },
+    "node_modules/fbjs/node_modules/core-js": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-1.2.7.tgz",
+      "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==",
+      "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js."
+    },
+    "node_modules/fbjs/node_modules/promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmmirror.com/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "dependencies": {
+        "asap": "~2.0.3"
+      }
+    },
     "node_modules/fflate": {
       "version": "0.4.8",
       "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.4.8.tgz",
@@ -8724,9 +8875,12 @@
       "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ=="
     },
     "node_modules/immutable": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.1.0.tgz",
-      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ=="
+      "version": "3.7.6",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-3.7.6.tgz",
+      "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
     },
     "node_modules/import-fresh": {
       "version": "3.3.0",
@@ -8816,6 +8970,14 @@
       "resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz",
       "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg=="
     },
+    "node_modules/invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "dependencies": {
+        "loose-envify": "^1.0.0"
+      }
+    },
     "node_modules/ipaddr.js": {
       "version": "2.0.1",
       "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz",
@@ -9145,6 +9307,15 @@
       "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
     },
+    "node_modules/isomorphic-fetch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+      "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==",
+      "dependencies": {
+        "node-fetch": "^1.0.1",
+        "whatwg-fetch": ">=0.10.0"
+      }
+    },
     "node_modules/istanbul-lib-coverage": {
       "version": "3.2.0",
       "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
@@ -11812,6 +11983,23 @@
         "tslib": "^2.0.3"
       }
     },
+    "node_modules/node-fetch": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-1.7.3.tgz",
+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "dependencies": {
+        "encoding": "^0.1.11",
+        "is-stream": "^1.0.1"
+      }
+    },
+    "node_modules/node-fetch/node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/node-forge": {
       "version": "1.3.1",
       "resolved": "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.1.tgz",
@@ -15217,6 +15405,11 @@
         }
       }
     },
+    "node_modules/sass/node_modules/immutable": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.4.tgz",
+      "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA=="
+    },
     "node_modules/sax": {
       "version": "1.2.4",
       "resolved": "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz",
@@ -15433,6 +15626,11 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+    },
     "node_modules/setprototypeof": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -16381,6 +16579,14 @@
         "node": ">=4.2.0"
       }
     },
+    "node_modules/ua-parser-js": {
+      "version": "0.7.37",
+      "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz",
+      "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/unbox-primitive": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -21488,6 +21694,67 @@
         "fill-range": "^7.0.1"
       }
     },
+    "braft-convert": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/braft-convert/-/braft-convert-2.3.0.tgz",
+      "integrity": "sha512-5km+dLHk8iYDv2iEYDrDQ2ld/ZoUx66QLql0qdm5PqZEcNXc8dBHGLORfzeu3iMw1jLeAiHxtdY5+ypuIhczVg==",
+      "requires": {
+        "draft-convert": "^2.0.0",
+        "draft-js": "^0.10.3"
+      },
+      "dependencies": {
+        "draft-convert": {
+          "version": "2.1.13",
+          "resolved": "https://registry.npmmirror.com/draft-convert/-/draft-convert-2.1.13.tgz",
+          "integrity": "sha512-/h/n4JCfyO8aWby7wKBkccHdsuVbbDyHWXi/B3Zf2pN++lN1lDOIVt5ulXCcbH2Y5YJEFzMJw/YGfN+R0axxxg==",
+          "requires": {
+            "@babel/runtime": "^7.5.5",
+            "immutable": "~3.7.4",
+            "invariant": "^2.2.1"
+          }
+        }
+      }
+    },
+    "braft-editor": {
+      "version": "2.3.9",
+      "resolved": "https://registry.npmmirror.com/braft-editor/-/braft-editor-2.3.9.tgz",
+      "integrity": "sha512-mqdPk/zI2dhFK8tW/A4Qj/AkkARLh5L/niNw+iif5wFqb6zh15rMlrShgz1nWO/QXyAKr8XtDgxiBbR0zWwtRg==",
+      "requires": {
+        "@babel/runtime": "^7.0.0",
+        "braft-convert": "^2.3.0",
+        "braft-finder": "^0.0.19",
+        "braft-utils": "^3.0.8",
+        "draft-convert": "^2.0.0",
+        "draft-js": "^0.10.3",
+        "draft-js-multidecorators": "^1.0.0",
+        "draftjs-utils": "^0.9.4",
+        "immutable": "~3.7.4"
+      },
+      "dependencies": {
+        "braft-finder": {
+          "version": "0.0.19",
+          "resolved": "https://registry.npmmirror.com/braft-finder/-/braft-finder-0.0.19.tgz",
+          "integrity": "sha512-0kzI6/KbomJJhYX1hpjn4edCKhblyUyWdUrsgBmOrwy0vrj+pPkm69+Uf8Uj6KGAULM6LF0ooC++p7fqUGgFHw==",
+          "requires": {}
+        },
+        "draft-convert": {
+          "version": "2.1.13",
+          "resolved": "https://registry.npmmirror.com/draft-convert/-/draft-convert-2.1.13.tgz",
+          "integrity": "sha512-/h/n4JCfyO8aWby7wKBkccHdsuVbbDyHWXi/B3Zf2pN++lN1lDOIVt5ulXCcbH2Y5YJEFzMJw/YGfN+R0axxxg==",
+          "requires": {
+            "@babel/runtime": "^7.5.5",
+            "immutable": "~3.7.4",
+            "invariant": "^2.2.1"
+          }
+        }
+      }
+    },
+    "braft-utils": {
+      "version": "3.0.12",
+      "resolved": "https://registry.npmmirror.com/braft-utils/-/braft-utils-3.0.12.tgz",
+      "integrity": "sha512-O2cKysURNC4HSEMKgNmQ2RluwcrxvYrztlEmyPN5SzktiNX3vaLFQoo0Ez3PlIhvjaGrIBSIT2Oyh2N6mn6TFg==",
+      "requires": {}
+    },
     "browser-process-hrtime": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
@@ -22533,6 +22800,30 @@
       "resolved": "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
       "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
     },
+    "draft-js": {
+      "version": "0.10.5",
+      "resolved": "https://registry.npmmirror.com/draft-js/-/draft-js-0.10.5.tgz",
+      "integrity": "sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg==",
+      "requires": {
+        "fbjs": "^0.8.15",
+        "immutable": "~3.7.4",
+        "object-assign": "^4.1.0"
+      }
+    },
+    "draft-js-multidecorators": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/draft-js-multidecorators/-/draft-js-multidecorators-1.0.0.tgz",
+      "integrity": "sha512-7qdy+YQol5iq38AoEerhgSJWhCzxvZLn1x5ODfUlGfWlg0SrZ9AXJbaxHVIjdSIZNrbVIm+WANujNxMqCmDSZQ==",
+      "requires": {
+        "immutable": "*"
+      }
+    },
+    "draftjs-utils": {
+      "version": "0.9.4",
+      "resolved": "https://registry.npmmirror.com/draftjs-utils/-/draftjs-utils-0.9.4.tgz",
+      "integrity": "sha512-KYjABSbGpJrwrwmxVj5UhfV37MF/p0QRxKIyL+/+QOaJ8J9z1FBKxkblThbpR0nJi9lxPQWGg+gh+v0dAsSCCg==",
+      "requires": {}
+    },
     "duplexer": {
       "version": "0.1.2",
       "resolved": "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz",
@@ -22592,6 +22883,14 @@
       "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
       "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
     },
+    "encoding": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+      "requires": {
+        "iconv-lite": "^0.6.2"
+      }
+    },
     "enhanced-resolve": {
       "version": "5.10.0",
       "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
@@ -23418,6 +23717,35 @@
         "bser": "2.1.1"
       }
     },
+    "fbjs": {
+      "version": "0.8.18",
+      "resolved": "https://registry.npmmirror.com/fbjs/-/fbjs-0.8.18.tgz",
+      "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==",
+      "requires": {
+        "core-js": "^1.0.0",
+        "isomorphic-fetch": "^2.1.1",
+        "loose-envify": "^1.0.0",
+        "object-assign": "^4.1.0",
+        "promise": "^7.1.1",
+        "setimmediate": "^1.0.5",
+        "ua-parser-js": "^0.7.30"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "1.2.7",
+          "resolved": "https://registry.npmmirror.com/core-js/-/core-js-1.2.7.tgz",
+          "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA=="
+        },
+        "promise": {
+          "version": "7.3.1",
+          "resolved": "https://registry.npmmirror.com/promise/-/promise-7.3.1.tgz",
+          "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+          "requires": {
+            "asap": "~2.0.3"
+          }
+        }
+      }
+    },
     "fflate": {
       "version": "0.4.8",
       "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.4.8.tgz",
@@ -24170,9 +24498,9 @@
       "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ=="
     },
     "immutable": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.1.0.tgz",
-      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ=="
+      "version": "3.7.6",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-3.7.6.tgz",
+      "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw=="
     },
     "import-fresh": {
       "version": "3.3.0",
@@ -24243,6 +24571,14 @@
       "resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz",
       "integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg=="
     },
+    "invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "requires": {
+        "loose-envify": "^1.0.0"
+      }
+    },
     "ipaddr.js": {
       "version": "2.0.1",
       "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz",
@@ -24494,6 +24830,15 @@
       "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
     },
+    "isomorphic-fetch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+      "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==",
+      "requires": {
+        "node-fetch": "^1.0.1",
+        "whatwg-fetch": ">=0.10.0"
+      }
+    },
     "istanbul-lib-coverage": {
       "version": "3.2.0",
       "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
@@ -26575,6 +26920,22 @@
         "tslib": "^2.0.3"
       }
     },
+    "node-fetch": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-1.7.3.tgz",
+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "requires": {
+        "encoding": "^0.1.11",
+        "is-stream": "^1.0.1"
+      },
+      "dependencies": {
+        "is-stream": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-1.1.0.tgz",
+          "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="
+        }
+      }
+    },
     "node-forge": {
       "version": "1.3.1",
       "resolved": "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.1.tgz",
@@ -28961,6 +29322,13 @@
         "chokidar": ">=3.0.0 <4.0.0",
         "immutable": "^4.0.0",
         "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "dependencies": {
+        "immutable": {
+          "version": "4.3.4",
+          "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.4.tgz",
+          "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA=="
+        }
       }
     },
     "sass-loader": {
@@ -29161,6 +29529,11 @@
         "send": "0.18.0"
       }
     },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+    },
     "setprototypeof": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -29918,6 +30291,11 @@
       "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.8.4.tgz",
       "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ=="
     },
+    "ua-parser-js": {
+      "version": "0.7.37",
+      "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz",
+      "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA=="
+    },
     "unbox-primitive": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz",

+ 2 - 0
houtai/package.json

@@ -13,6 +13,8 @@
     "@types/react-dom": "^18.0.8",
     "antd": "^5.0.4",
     "axios": "^1.1.3",
+    "braft-editor": "^2.3.9",
+    "braft-utils": "^3.0.12",
     "dayjs": "^1.11.7",
     "echarts": "^5.4.0",
     "file-saver": "^2.0.5",

+ 53 - 0
houtai/src/components/Z_RichText/index.module.scss

@@ -0,0 +1,53 @@
+.RichText {
+  :global {
+    .txtBox {
+      width: 1000px;
+      border: 1px solid #ccc;
+
+      // 隐藏媒体功能
+      .control-item.media {
+        display: none;
+      }
+
+      .bf-controlbar {
+        position: relative;
+
+        .upImgBox {
+          position: absolute;
+          bottom: 13px;
+          right: 15px;
+          cursor: pointer;
+          color: var(--themeColor);
+        }
+
+        .upImgBoxNo {
+          display: none;
+        }
+
+      }
+    }
+
+    .noUpThumb {
+      position: relative;
+      overflow: hidden;
+      opacity: 0;
+      transition: top .2s;
+      color: #ff4d4f;
+      top: -10px;
+    }
+
+    .noUpThumbAc {
+      top: 0;
+      opacity: 1;
+    }
+
+    .bf-media .bf-image {
+      float: initial !important;
+      display: block;
+      margin: 10px auto;
+      max-width: 500px;
+      max-height: 500px;
+    }
+
+  }
+}

+ 194 - 0
houtai/src/components/Z_RichText/index.tsx

@@ -0,0 +1,194 @@
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import styles from "./index.module.scss";
+
+// 引入编辑器组件
+
+// 安装---npm install braft-editor --save --force
+// npm install braft-utils --save --force
+import { ContentUtils } from "braft-utils";
+import BraftEditor from "braft-editor";
+// 引入编辑器样式
+import "braft-editor/dist/index.css";
+
+import classNames from "classnames";
+import { MessageFu } from "@/utils/message";
+import { fileDomInitialFu } from "@/utils/domShow";
+import { baseURL } from "@/utils/http";
+
+import { forwardRef, useImperativeHandle } from "react";
+// import { A1_APIupFile } from "@/store/action/A1Plate";
+
+type Props = {
+  check: boolean; //表单校验,为fasle表示不校验
+  dirCode: string; //文件的code码
+  isLook: boolean; //是否是查看进来
+  ref: any; //当前自己的ref,给父组件调用
+  myUrl: string; //上传的api地址
+};
+
+function RichText({ check, dirCode, isLook, myUrl }: Props, ref: any) {
+  // 添加 上传 图片的dom
+  useEffect(() => {
+    if (!isLook) {
+      setTimeout(() => {
+        const dom = document.querySelector(".bf-controlbar")!;
+        const div = document.createElement("div");
+        div.className = "upImgBox";
+        // div.title = "上传图片";
+        div.innerHTML = "上传图片";
+        div.onclick = async () => {
+          myInput.current?.click();
+        };
+        dom.appendChild(div);
+      }, 200);
+
+      // 监听 富文本 的 class 变化,在全屏的时候会 富文本会添加上 fullscreen 的类
+      // 修复顶部样式冲突问题
+
+      const editorDom = document.querySelector(
+        ".bf-container"
+      ) as HTMLDivElement;
+
+      const observer = new MutationObserver(() => {
+        // console.log("change");
+        const dom = document.querySelector(".layoutRightTop") as HTMLDivElement;
+
+        if (editorDom.className.includes("fullscreen")) dom.style.zIndex = "-1";
+        else dom.style.zIndex = "100";
+      });
+
+      observer.observe(editorDom, {
+        attributes: true,
+      });
+
+      // 销毁监听
+      return () => {
+        observer.disconnect();
+      };
+    }
+  }, [isLook]);
+
+  // 编辑器文本
+  const [editorValue, setEditorValue] = useState(
+    // 初始内容
+    BraftEditor.createEditorState("")
+  );
+
+  // 判断 富文本是否为空
+  const isTxtFlag = useMemo(() => {
+    const txt: string = editorValue.toHTML();
+    if (
+      txt.replaceAll("<p>", "").replaceAll("</p>", "").replaceAll(" ", "") ===
+      ""
+    ) {
+      return true;
+    } else return false;
+  }, [editorValue]);
+
+  const myInput = useRef<HTMLInputElement>(null);
+
+  // 上传图片
+  const handeUpPhoto = useCallback(
+    async (e: React.ChangeEvent<HTMLInputElement>) => {
+      if (e.target.files) {
+        // 拿到files信息
+        const filesInfo = e.target.files[0];
+        // 校验格式
+        const type = ["image/jpeg", "image/png"];
+        if (!type.includes(filesInfo.type)) {
+          e.target.value = "";
+          return MessageFu.warning("只支持png、jpg和jpeg格式!");
+        }
+        // 校验大小
+        if (filesInfo.size > 5 * 1024 * 1024) {
+          e.target.value = "";
+          return MessageFu.warning("最大支持5M!");
+        }
+        // 创建FormData对象
+        const fd = new FormData();
+        // 把files添加进FormData对象(‘photo’为后端需要的字段)
+        fd.append("type", "img");
+        fd.append("dirCode", dirCode);
+        fd.append("file", filesInfo);
+
+        e.target.value = "";
+
+        try {
+          // const res = await A1_APIupFile(fd, myUrl);
+          // if (res.code === 0) {
+          //   MessageFu.success("上传成功!");
+          //   // 在光标位置插入图片
+          //   const newTxt = ContentUtils.insertMedias(editorValue, [
+          //     {
+          //       type: "IMAGE",
+          //       url: baseURL + res.data.filePath,
+          //     },
+          //   ]);
+
+          //   setEditorValue(newTxt);
+          // }
+          fileDomInitialFu();
+        } catch (error) {
+          fileDomInitialFu();
+        }
+      }
+    },
+    [dirCode]
+  );
+
+  // 让父组件调用的 回显 富文本
+  const ritxtShowFu = useCallback((val: string) => {
+    setEditorValue(BraftEditor.createEditorState(val));
+  }, []);
+
+  // 让父组件调用的返回 富文本信息 和 表单校验
+  const fatherBtnOkFu = useCallback(() => {
+    return { val: editorValue.toHTML(), flag: isTxtFlag };
+  }, [editorValue, isTxtFlag]);
+
+  // 可以让父组件调用子组件的方法
+  useImperativeHandle(ref, () => ({
+    ritxtShowFu,
+    fatherBtnOkFu,
+  }));
+
+  return (
+    <div className={styles.RichText}>
+      <input
+        id="upInput"
+        type="file"
+        accept=".png,.jpg,.jpeg"
+        ref={myInput}
+        onChange={(e) => handeUpPhoto(e)}
+      />
+
+      <div className="txtBox">
+        <BraftEditor
+          readOnly={isLook}
+          placeholder="请输入内容"
+          value={editorValue}
+          onChange={(e:any) => setEditorValue(e)}
+          imageControls={["remove"]}
+        />
+      </div>
+      <div
+        className={classNames(
+          "noUpThumb",
+          check && isTxtFlag ? "noUpThumbAc" : ""
+        )}
+      >
+        请输入正文!
+      </div>
+    </div>
+  );
+}
+
+// const MemoRichText = React.memo(RichText);
+
+export default forwardRef(RichText);

+ 19 - 0
houtai/src/pages/A1Rule/RuleEdit/index.module.scss

@@ -0,0 +1,19 @@
+.RuleEdit {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .userAddMain {
+      border-top: 1px solid #999999;
+      padding-top: 15px;
+      width: 100%;
+
+      .passTit {
+        color: #ff4d4f;
+        font-size: 14px;
+        padding-left: 98px;
+      }
+    }
+  }
+}

+ 237 - 0
houtai/src/pages/A1Rule/RuleEdit/index.tsx

@@ -0,0 +1,237 @@
+import { getRuleInfoByIdAPI, ruleSaveAPI } from "@/store/action/A1Rule";
+import { SaveRuleType } from "@/types";
+import { MessageFu } from "@/utils/message";
+import { Button, Form, FormInstance, Input, Modal, Popconfirm } from "antd";
+import React, { useCallback, useEffect, useRef, useState } from "react";
+import styles from "./index.module.scss";
+import RichText from "@/components/Z_RichText";
+
+type Props = {
+  id: any;
+  closePage: () => void;
+  upTableList: () => void;
+  editMode: number;
+};
+
+function RuleEdit({ id, closePage, upTableList, editMode }: Props) {
+  // 设置表单初始数据(区分编辑和新增)
+  const FormBoxRef = useRef<FormInstance>(null);
+
+  const currentIdInfo = useRef(null);
+
+  // 富文本的ref
+  const richTxtRef = useRef<any>(null);
+
+  // 文件的校验
+  const [check, setCheck] = useState(false);
+
+  // 文件的code码
+  const [dirCode, setDirCode] = useState("");
+
+  const getInfoInAPIFu = useCallback(async (id: number) => {
+    const res = await getRuleInfoByIdAPI(id);
+    FormBoxRef.current?.setFieldsValue(res.data);
+
+    // 富文本回显
+    richTxtRef.current.ritxtShowFu(res.data.content);
+    currentIdInfo.current = res.data;
+  }, []);
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    // return MessageFu.warning("有表单不符号规则!");
+  }, []);
+
+  useEffect(() => {
+    if (id) getInfoInAPIFu(id);
+    else {
+      FormBoxRef.current?.setFieldsValue({});
+    }
+  }, [getInfoInAPIFu, id]);
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      const obj: SaveRuleType = {
+        ...values,
+        id: id ? id : null,
+      };
+
+      const res: any = await ruleSaveAPI(obj);
+
+      if (res.code === 0) {
+        MessageFu.success(id ? "编辑成功!" : "新增成功!");
+        if (id) upTableList();
+        else;
+
+        closePage();
+      }
+      console.log("通过校验,点击确定");
+    },
+    [closePage, id, upTableList]
+  );
+
+  return (
+    <>
+      {editMode === 1 ? (
+        <Modal
+          wrapClassName={styles.RuleEdit}
+          destroyOnClose
+          open={true}
+          // title={currentIdInfo ? currentIdInfo : "编辑"}
+          title="编辑"
+          footer={
+            [] // 设置footer为空,去掉 取消 确定默认按钮
+          }
+        >
+          <div className="userAddMain">
+            <Form
+              ref={FormBoxRef}
+              name="basic"
+              labelCol={{ span: 5 }}
+              onFinish={onFinish}
+              onFinishFailed={onFinishFailed}
+              autoComplete="off"
+            >
+              <Form.Item
+                label="时限(秒)"
+                name="time"
+                rules={[{ required: true, message: "请输入时限!" }]}
+                getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+              >
+                <Input
+                  disabled={id}
+                  maxLength={3}
+                  showCount
+                  placeholder="请输入数字,1-300"
+                />
+              </Form.Item>
+
+              <Form.Item
+                label="得分"
+                name="score"
+                rules={[{ required: true, message: "请输入游戏得分!" }]}
+                getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+              >
+                <Input
+                  maxLength={6}
+                  showCount
+                  placeholder="请输入数字,1-99999"
+                />
+              </Form.Item>
+
+              <Form.Item
+                label="得分说明"
+                name="specification"
+                rules={[{ required: true, message: "请输入得分说明!" }]}
+                getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+              >
+                {/* <Input maxLength={8} showCount placeholder="请输入内容" /> */}
+                <span>currentIdInfo.specification</span>
+              </Form.Item>
+
+              <Form.Item
+                label="游戏规则"
+                name="gameRule"
+                getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+              >
+                <RichText
+                  myUrl="cms/goods/upload"
+                  ref={richTxtRef}
+                  check={check}
+                  dirCode={dirCode}
+                  isLook={true}
+                />
+              </Form.Item>
+
+              {/* {id ? null : <div className="passTit">* 默认密码 123456</div>} */}
+
+              {/* 确定和取消按钮 */}
+              <br />
+              <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+                <Button type="primary" htmlType="submit">
+                  提交
+                </Button>
+                &emsp;
+                <Popconfirm
+                  title="放弃编辑后,信息将不会保存!"
+                  okText="放弃"
+                  cancelText="取消"
+                  onConfirm={closePage}
+                  okButtonProps={{ loading: false }}
+                >
+                  <Button>取消</Button>
+                </Popconfirm>
+              </Form.Item>
+            </Form>
+          </div>
+        </Modal>
+      ) : (
+        <Modal
+          wrapClassName={styles.RuleEdit}
+          destroyOnClose
+          open={true}
+          title="观看视频"
+          footer={
+            [] // 设置footer为空,去掉 取消 确定默认按钮
+          }
+        >
+          <div className="userAddMain">
+            <Form
+              ref={FormBoxRef}
+              name="basic"
+              labelCol={{ span: 5 }}
+              onFinish={onFinish}
+              onFinishFailed={onFinishFailed}
+              autoComplete="off"
+            >
+              <Form.Item
+                label="得分"
+                name="score"
+                rules={[{ required: true, message: "请输入游戏得分!" }]}
+                getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+              >
+                <Input
+                  maxLength={6}
+                  showCount
+                  placeholder="请输入数字,1-99999"
+                />
+              </Form.Item>
+
+              <Form.Item
+                label="得分说明"
+                name="specification"
+                rules={[{ required: true, message: "请输入得分说明!" }]}
+                getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+              >
+                {/* <Input maxLength={8} showCount placeholder="请输入内容" /> */}
+                <span>currentIdInfo.specification</span>
+              </Form.Item>
+              {/* 确定和取消按钮 */}
+              <br />
+              <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+                <Button type="primary" htmlType="submit">
+                  提交
+                </Button>
+                &emsp;
+                <Popconfirm
+                  title="放弃编辑后,信息将不会保存!"
+                  okText="放弃"
+                  cancelText="取消"
+                  onConfirm={closePage}
+                  okButtonProps={{ loading: false }}
+                >
+                  <Button>取消</Button>
+                </Popconfirm>
+              </Form.Item>
+            </Form>
+          </div>
+        </Modal>
+      )}
+    </>
+  );
+}
+
+const MemoRuleEdit = React.memo(RuleEdit);
+
+export default MemoRuleEdit;

+ 87 - 3
houtai/src/pages/A1Rule/index.module.scss

@@ -1,5 +1,89 @@
-.AAAAA{
-  :global{
-    
+.A1Rule {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  background-color: rgb(239, 239, 239);
+
+  :global {
+    .ruleTop {
+      border-radius: 4px;
+      padding: 15px 20px 25px 20px;
+      background-color: #fff;
+      box-shadow: 3px 0px 10px 0px #d5d5d9;
+      position: relative;
+
+      .pageTitle {
+        .exportBtn {
+          width: 100px;
+          height: 40px;
+        }
+      }
+
+      .scoreLimitBtn {
+        position: absolute;
+        right: 2.5%;
+        top: 3%;
+        height: 30px;
+        padding: 0 10px;
+        background: #1F5CD8;
+        color: white;
+        border: 1px solid white;
+        border-radius: 5px;
+        cursor: pointer;
+        z-index: 10;
+        // transform: translateY(-50%);
+      }
+
+      .tableBox1 {
+        border-radius: 4px;
+        overflow: hidden;
+        margin-top: -10px;
+        // height: calc(100% - 80px);
+        // background-color: #fff;
+        padding: 0px;
+        // box-shadow: 3px 0px 10px 0px #d5d5d9;
+
+        .ant-table-body {
+          height: 300px;
+          overflow-y: auto !important;
+          overflow-y: overlay !important;
+
+          .ant-table-row {
+            .ant-table-cell {
+              padding: 10px;
+            }
+          }
+        }
+      }
+    }
+
+    .ruleBottom {
+      margin-top: 10px;
+
+      .tableBox2 {
+        border-radius: 4px;
+        overflow: hidden;
+        margin-top: -10px;
+        // height: calc(100% - 80px);
+        // background-color: #fff;
+        padding: 0px;
+        // box-shadow: 3px 0px 10px 0px #d5d5d9;
+
+        .ant-table-body {
+          height: 200px;
+          overflow-y: auto !important;
+          overflow-y: overlay !important;
+
+          .ant-table-row {
+            .ant-table-cell {
+              padding: 10px;
+            }
+          }
+        }
+      }
+    }
+
+
   }
 }

+ 264 - 8
houtai/src/pages/A1Rule/index.tsx

@@ -1,14 +1,270 @@
-import React from "react";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
 import styles from "./index.module.scss";
- function AAAAA() {
-  
+import { Button, Form, Input, Modal, Popconfirm, Table } from "antd";
+import { useDispatch, useSelector } from "react-redux";
+import { RootState } from "@/store";
+import { RulesTableType, SaveScoreLimitType } from "@/types";
+import {
+  getRuleAPI,
+  getScoreLimitAPI,
+  scoreLimitSaveAPI,
+} from "@/store/action/A1Rule";
+import RuleEdit from "./RuleEdit";
+import { MessageFu } from "@/utils/message";
+function A1Rule() {
+  const dispatch = useDispatch();
+
+  // 从仓库中获取表格数据
+  const tableInfo = useSelector((state: RootState) => state.A1Rule.tableInfo);
+
+  const [editPageShow, setEditPageShow] = useState(false);
+
+  const [surScoreLimit, setSurScoreLimit] = useState({} as any);
+
+  const getList = useCallback(async () => {
+    dispatch(getRuleAPI());
+    const res = await getScoreLimitAPI();
+    if (res.code === 0) {
+      setSurScoreLimit(res.data);
+    }
+  }, [dispatch]);
+
+  // 积分上限窗口开关
+  const [limitScoreShow, setLimitScoreShow] = useState(false);
+
+  // 编辑游戏
+  const editId = useRef(0);
+  // 编辑模式 1是游戏规则 2是线上展厅
+  const editMode = useRef(1);
+  const openEditPageFu = useCallback((type: number, id: number) => {
+    editMode.current = type;
+    editId.current = id;
+    setEditPageShow(true);
+  }, []);
+
+  const [form] = Form.useForm();
+
+  const onFinish = useCallback(
+    async (values: any) => {
+      if (values.numberVal) {
+        const res: any = await scoreLimitSaveAPI({} as SaveScoreLimitType);
+        if (res.code === 0) {
+          MessageFu.success("提交成功!");
+          getList();
+          setLimitScoreShow(false);
+        }
+      }
+    },
+    [getList]
+  );
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "游戏名称",
+        dataIndex: "gameName",
+      },
+      {
+        title: "时限(秒)",
+        render: (item: RulesTableType) => {
+          return item.name === "乡村林场" ? <>-</> : <>60</>;
+        },
+      },
+      {
+        title: "得分",
+        dataIndex: "score",
+      },
+      {
+        title: "得分说明",
+        dataIndex: "specification",
+      },
+      {
+        title: "操作",
+        render: (item: RulesTableType) => {
+          return item.name === "助农课堂" ? (
+            <>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => openEditPageFu(1, item.id!)}
+              >
+                编辑
+              </Button>
+              <Button size="small" type="text">
+                设置题目
+              </Button>
+            </>
+          ) : (
+            <>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => openEditPageFu(1, item.id!)}
+              >
+                编辑
+              </Button>
+            </>
+          );
+        },
+      },
+    ];
+  }, [openEditPageFu]);
+  const columns2 = useMemo(() => {
+    return [
+      {
+        title: "事件名称",
+        dataIndex: "eventName",
+      },
+      {
+        title: "得分",
+        dataIndex: "score",
+      },
+      {
+        title: "得分说明",
+        dataIndex: "specification",
+      },
+      {
+        title: "操作",
+        render: (item: RulesTableType) => {
+          return (
+            <>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => openEditPageFu(2, item.id!)}
+              >
+                编辑
+              </Button>
+            </>
+          );
+        },
+      },
+    ];
+  }, [openEditPageFu]);
+
+  useEffect(() => {
+    dispatch(getRuleAPI());
+  }, [dispatch]);
   return (
-    <div className={styles.AAAAA}>
-      <h1>AAAAA</h1>
+    <div className={styles.A1Rule}>
+      <div className="ruleTop">
+        <div className="pageTitle">游戏规则</div>
+        <button
+          className="scoreLimitBtn"
+          onClick={() => {
+            console.log("打开");
+            setLimitScoreShow(true);
+          }}
+        >
+          单日可获得积分上线:5000
+        </button>
+        {/* 表格主体 */}
+        <div className="tableBox1">
+          <Table
+            scroll={{ y: 500 }}
+            bordered={false}
+            dataSource={tableInfo.list}
+            columns={columns}
+            rowKey="id"
+            pagination={{
+              showQuickJumper: true,
+              position: ["bottomCenter"],
+              showSizeChanger: true,
+              total: tableInfo.total,
+            }}
+          />
+        </div>
+      </div>
+      <div className="ruleTop ruleBottom">
+        <div className="pageTitle">线上展厅</div>
+        {/* 表格主体 */}
+        <div className="tableBox2">
+          <Table
+            scroll={{ y: 500 }}
+            bordered={false}
+            dataSource={tableInfo.list}
+            columns={columns2}
+            rowKey="id"
+            pagination={{
+              showQuickJumper: true,
+              position: ["bottomCenter"],
+              showSizeChanger: true,
+              total: tableInfo.total,
+            }}
+          />
+        </div>
+      </div>
+      {/* 点击游戏编辑 */}
+      {editPageShow && editMode.current === 1 ? (
+        <RuleEdit
+          id={editId.current}
+          closePage={() => setEditPageShow(false)}
+          upTableList={getList}
+          editMode={editMode.current}
+        />
+      ) : null}
+      {/* 设置积分上线弹窗 */}
+      <Modal
+        destroyOnClose
+        closable={false}
+        maskClosable={false}
+        open={limitScoreShow}
+        title="   "
+        onCancel={() => setLimitScoreShow(false)}
+        footer={
+          [] // 设置footer为空,去掉 取消 确定默认按钮
+        }
+      >
+        <Form
+          form={form}
+          name="basic"
+          labelCol={{ span: 8 }}
+          onFinish={onFinish}
+          autoComplete="off"
+        >
+          <Form.Item
+            label="单日可获得积分上限"
+            name="numberVal"
+            style={{ marginTop: "40px" }}
+            rules={[{ required: true, message: "不能为空!" }]}
+            hide-required-asterisk={true}
+            getValueFromEvent={(e) =>
+              e.target.value.replace(/^(0+)|[^\d]+/g, "")
+            }
+          >
+            <Input maxLength={9} placeholder="请输入正整数,不超过999999999" />
+          </Form.Item>
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+            <Button type="primary" htmlType="submit">
+              提交
+            </Button>
+            &emsp;
+            <Popconfirm
+              title="放弃编辑后,信息将不会保存!"
+              okText="放弃"
+              cancelText="取消"
+              onConfirm={() => {
+                setLimitScoreShow(false);
+              }}
+              okButtonProps={{ loading: false }}
+            >
+              <Button>取消</Button>
+            </Popconfirm>
+          </Form.Item>
+        </Form>
+      </Modal>
     </div>
-  )
+  );
 }
 
-const MemoAAAAA = React.memo(AAAAA);
+const MemoA1Rule = React.memo(A1Rule);
 
-export default MemoAAAAA;
+export default MemoA1Rule;

+ 33 - 7
houtai/src/store/action/A1Rule.ts

@@ -1,23 +1,49 @@
 import http from "@/utils/http";
 import { AppDispatch } from "..";
+import { SaveRuleType, SaveScoreLimitType } from "@/types";
 // import { AxiosRequestConfig } from "axios";
 /**
- * 获取浏览量信息
+ * 获取游戏规则列表
  */
-export const getShareAPI = () => {
+export const getRuleAPI = () => {
   return async (dispatch: AppDispatch) => {
     const res = await http.get(`cms/share/detail/museum_cctv_mianyan`);
     if (res.code === 0) {
       const data = res.data;
-      dispatch({ type: "Share/getShare", payload: data });
+      dispatch({ type: "rules/getList", payload: data });
     }
   };
 };
 
 /**
- * 提交参与者基数
+ * 修改游戏规则
  */
-export const shareEditAPI = (data: any) => {
-  // return http.post(`/cms/share/save/`, data);
-  return http.post(`cms/share/edit/`, data);
+export const ruleSaveAPI = (data: SaveRuleType) => {
+  return http.post("sys/user/save", data);
 };
+
+/**
+ * 获取游戏info
+ */
+export const getRuleInfoByIdAPI = (id: number) => {
+  return http.get(`sys/user/detail/${id}`);
+};
+
+
+/**
+ * 获得每日积分上限
+ */
+export const getScoreLimitAPI = () => {
+  return http.get("sys/user/save");
+};
+
+
+/**
+ * 保存每日积分上限
+ */
+export const scoreLimitSaveAPI = (data: SaveScoreLimitType) => {
+  return http.post("sys/user/save", data);
+};
+
+
+

+ 7 - 6
houtai/src/store/reducer/A1Rule.ts

@@ -1,20 +1,21 @@
-import { GoodsTableType } from "@/types";
+import { RulesTableType } from "@/types";
 
 // 初始化状态
 const initState = {
   // 列表数据
   tableInfo: {
-    list: [] as GoodsTableType[],
+    list: [] as RulesTableType[],
     total: 0,
   },
 };
 
 // 定义 action 类型
 type GoodsActionType = {
-  type: "goods/getList";
-  payload: { list: GoodsTableType[]; total: number };
+  type: "rules/getList";
+  payload: { list: RulesTableType[]; total: number };
 };
 
+
 // 频道 reducer
 export default function goodsReducer(
   state = initState,
@@ -22,9 +23,9 @@ export default function goodsReducer(
 ) {
   switch (action.type) {
     // 获取列表数据
-    case "goods/getList":
+    case "rules/getList":
       return { ...state, tableInfo: action.payload };
     default:
       return state;
   }
-}
+}

+ 57 - 0
houtai/src/types/api/A1Rule.ts

@@ -0,0 +1,57 @@
+export type RulesTableType = {
+  createTime: string;
+  creatorId: number;
+  creatorName: string;
+  description: string;
+  dictAge: string;
+  dictLevel: string;
+  dictSource: string;
+  dictTexture: string;
+  dirCode: string;
+  display: number;
+  fileIds: string;
+  id: number;
+  isBarrage: number;
+  name: string;
+  num: string;
+  thumb: string;
+  topic: string;
+  type: string;
+  updateTime: string;
+  tagType?: string;
+  tagCountry?: string;
+};
+
+export type FileListType = {
+  fileName?: string;
+  filePath?: string;
+  id?: number;
+  isFrame?: boolean;
+  done?: boolean;
+  type?: "model" | "img" | "audio" | "video";
+};
+
+export type FileImgListType = {
+  id: number;
+  fileName: string;
+  filePath: string;
+};
+
+
+
+export type SaveRuleType ={
+  id:number|null
+  userName:string
+  nickName:string
+  roleId:number
+  realName:string
+}
+
+
+export type SaveScoreLimitType ={
+  id:number|null
+  userName:string
+  nickName:string
+  roleId:number
+  realName:string
+}

+ 1 - 0
houtai/src/types/declaration.d.ts

@@ -4,3 +4,4 @@ declare module "*.png";
 declare module "*.jpg";
 declare module "*.gif";
 declare module "js-export-excel";
+declare module 'braft-utils';

+ 1 - 0
houtai/src/types/index.d.ts

@@ -1,4 +1,5 @@
 export * from './api/layot'
+export * from './api/A1Rule'
 export * from './api/A1Goods'
 export * from './api/A3User'
 export * from './api/A4Role'