Compare commits
425 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de0c040cb3 | ||
|
|
23276bb0fd | ||
|
|
46c53e09a3 | ||
|
|
209eb019d3 | ||
|
|
10a608c0af | ||
|
|
098d4bc85f | ||
|
|
26f7d67c50 | ||
|
|
42d2525b46 | ||
|
|
d9305c7620 | ||
|
|
185d87c24e | ||
|
|
a4080490bd | ||
|
|
714bcbdbb1 | ||
|
|
9158a38496 | ||
|
|
1f1f7f167f | ||
|
|
9453cc1c3b | ||
|
|
33a03d8119 | ||
|
|
2292fd1df6 | ||
|
|
18ac428a95 | ||
|
|
f0d0c304d6 | ||
|
|
7f041c96fb | ||
|
|
53ca11f85b | ||
|
|
a9f2a0c2ac | ||
|
|
181e2b21bb | ||
|
|
04bc6b4cb8 | ||
|
|
6058a1741b | ||
|
|
455f11af34 | ||
|
|
0b8848d63f | ||
|
|
1b7d6d09a8 | ||
|
|
c9592446c8 | ||
|
|
f2d2055f72 | ||
|
|
21ce0789ef | ||
|
|
794a8fc6aa | ||
|
|
408ef4a7df | ||
|
|
ab9b357c9b | ||
|
|
68d072cd60 | ||
|
|
aae1d37505 | ||
|
|
e927f2ff78 | ||
|
|
c271f3005a | ||
|
|
ca5697fb9c | ||
|
|
9150101498 | ||
|
|
6d0e6d0d16 | ||
|
|
c4236937b7 | ||
|
|
c1c0774572 | ||
|
|
fcb0ea9574 | ||
|
|
f095fde5a7 | ||
|
|
8bc2db1e6e | ||
|
|
7cbc15ea85 | ||
|
|
c2a9c670c4 | ||
|
|
4e5bdf6847 | ||
|
|
0aa6443a20 | ||
|
|
04278f553e | ||
|
|
349a041d71 | ||
|
|
58bf5062bf | ||
|
|
878f24ecae | ||
|
|
a15a374fb0 | ||
|
|
8a90f9d089 | ||
|
|
3007267951 | ||
|
|
710bb97cd3 | ||
|
|
18eb3a7fbf | ||
|
|
1d499b7052 | ||
|
|
36b28d83ed | ||
|
|
04fc03ccf5 | ||
|
|
ffb5898ea1 | ||
|
|
2c2eb0cb8d | ||
|
|
15dd8a60d7 | ||
|
|
65a0a6fb92 | ||
|
|
a0b35f4233 | ||
|
|
a271bc25c6 | ||
|
|
c988ed7988 | ||
|
|
c2ca0b1f29 | ||
|
|
efee87e4c5 | ||
|
|
98a990d9ea | ||
|
|
3a61df42ea | ||
|
|
d62baa0e51 | ||
|
|
dfe8806344 | ||
|
|
f1e95b960a | ||
|
|
7d0fa7f5d1 | ||
|
|
174f247a8e | ||
|
|
9cc41e8558 | ||
|
|
1fe8b9c5c9 | ||
|
|
496861587d | ||
|
|
93764fc5b5 | ||
|
|
22fab8dee0 | ||
|
|
dcbd729944 | ||
|
|
327a7b2a48 | ||
|
|
ad6bd8f39b | ||
|
|
95a91a10b3 | ||
|
|
b50f2b4c7e | ||
|
|
a1e0dac85c | ||
|
|
027f6dd538 | ||
|
|
94f902f788 | ||
|
|
bc5aaff9c9 | ||
|
|
770e8d7310 | ||
|
|
6a881e4613 | ||
|
|
0f36672783 | ||
|
|
7d5a7e0fe8 | ||
|
|
6977e233bb | ||
|
|
dbcb27e41a | ||
|
|
4b5b4464f4 | ||
|
|
4b6241e0b0 | ||
|
|
17fb60c481 | ||
|
|
51575b9f2d | ||
|
|
c943c1fc74 | ||
|
|
b55a45baa2 | ||
|
|
ae5db16d67 | ||
|
|
8f143be4b0 | ||
|
|
9ebafff392 | ||
|
|
e904c3df69 | ||
|
|
8ed1c958af | ||
|
|
a93e65df0a | ||
|
|
2fd861025a | ||
|
|
654c7d650a | ||
|
|
cb75196455 | ||
|
|
dd2b584c3d | ||
|
|
85d1cbff34 | ||
|
|
92d9c532c2 | ||
|
|
24bc61396e | ||
|
|
1655870d4d | ||
|
|
9b1a978cb5 | ||
|
|
fb27fb8aa4 | ||
|
|
a612af4f68 | ||
|
|
eb8e076732 | ||
|
|
0401e97ed3 | ||
|
|
c4f25b7a41 | ||
|
|
ef5b628b31 | ||
|
|
543c13d94b | ||
|
|
b9dad93c9d | ||
|
|
18696ec542 | ||
|
|
5efdffcda8 | ||
|
|
ccd39474c7 | ||
|
|
386ec5ade0 | ||
|
|
ee6b3b535c | ||
|
|
d5ee57f04d | ||
|
|
b6c70bad45 | ||
|
|
921d35367b | ||
|
|
253bd47c75 | ||
|
|
8fa10cd8c1 | ||
|
|
01e5b52500 | ||
|
|
9c921adc5b | ||
|
|
b90962943a | ||
|
|
ad4fc6ea9b | ||
|
|
62310ab863 | ||
|
|
ef7b8cd98f | ||
|
|
5e128ebf04 | ||
|
|
b324d98125 | ||
|
|
8329728b81 | ||
|
|
ba220e9d55 | ||
|
|
6b2ef71296 | ||
|
|
bcf7802f94 | ||
|
|
769e2cb897 | ||
|
|
d55caf2278 | ||
|
|
69ca6677e9 | ||
|
|
3d94626ff1 | ||
|
|
5458819ef5 | ||
|
|
2ff8aef1bf | ||
|
|
16556ddb84 | ||
|
|
aef6fe9229 | ||
|
|
e5460ae3cc | ||
|
|
b6f4cbfb4f | ||
|
|
c83fcb7f26 | ||
|
|
ab0d126c49 | ||
|
|
fd3142bc19 | ||
|
|
af80d8e89b | ||
|
|
c98eefe3ec | ||
|
|
84ec0a7e1c | ||
|
|
4babe3e05d | ||
|
|
8213f6f8d7 | ||
|
|
30329ea4db | ||
|
|
4b856c4905 | ||
|
|
418f4a4785 | ||
|
|
2d31aeecd1 | ||
|
|
b3b3ca3fe4 | ||
|
|
5a4ac549f6 | ||
|
|
f4cdeb3dc5 | ||
|
|
7b01d4722f | ||
|
|
019c73ceca | ||
|
|
10fef4e2d9 | ||
|
|
c613b185da | ||
|
|
1bb7ce6805 | ||
|
|
9b3d8b5a06 | ||
|
|
5f603e6652 | ||
|
|
a20bd6933b | ||
|
|
13ea3ae9b3 | ||
|
|
a73920f4c3 | ||
|
|
543d54f844 | ||
|
|
4bd374e747 | ||
|
|
295cf5e066 | ||
|
|
2824e1325d | ||
|
|
cd9e27bcf3 | ||
|
|
9600e450af | ||
|
|
8e56667760 | ||
|
|
1eac218910 | ||
|
|
27962cd25f | ||
|
|
3de32945f2 | ||
|
|
9593b68d33 | ||
|
|
9166fc50aa | ||
|
|
fb5342594f | ||
|
|
733ff867e9 | ||
|
|
d3f9b43b12 | ||
|
|
30ab479315 | ||
|
|
9d3559cddb | ||
|
|
6d3edff5b6 | ||
|
|
619471369d | ||
|
|
2d328234a1 | ||
|
|
06acfe1ee3 | ||
|
|
a55cba4c1f | ||
|
|
61f8a07753 | ||
|
|
e0da9e1a87 | ||
|
|
3ba3ea6317 | ||
|
|
834e40d6f2 | ||
|
|
f93cccd849 | ||
|
|
0127b43374 | ||
|
|
5cea38e95c | ||
|
|
964b8aa5f6 | ||
|
|
33616de6c8 | ||
|
|
6bf490f7da | ||
|
|
3e31f7783f | ||
|
|
05f5122c0b | ||
|
|
93de208ac0 | ||
|
|
272466bbbf | ||
|
|
8639372513 | ||
|
|
49acf0c7c9 | ||
|
|
232cbad5bd | ||
|
|
aa2f9d4f50 | ||
|
|
99aa7d3361 | ||
|
|
72decd970a | ||
|
|
fa4e0b3752 | ||
|
|
6615229003 | ||
|
|
24300e6e50 | ||
|
|
f8445ab2e4 | ||
|
|
9645decf59 | ||
|
|
f34c33b0d8 | ||
|
|
5cd20b1e22 | ||
|
|
d65c565127 | ||
|
|
2f654a1772 | ||
|
|
380f728de2 | ||
|
|
dffdaa8d68 | ||
|
|
1f33204697 | ||
|
|
0566606bfb | ||
|
|
e6f95d0cd8 | ||
|
|
8eda2cd814 | ||
|
|
961634981a | ||
|
|
50aadb574d | ||
|
|
a114457c6f | ||
|
|
9274d88c76 | ||
|
|
97bf39f031 | ||
|
|
158cab9f9b | ||
|
|
bc42efe703 | ||
|
|
e2e1d2ad78 | ||
|
|
772f2695e7 | ||
|
|
5df1144cd0 | ||
|
|
943a7344f6 | ||
|
|
5867559502 | ||
|
|
fdd1eda9ec | ||
|
|
1d7c17e253 | ||
|
|
95484877a3 | ||
|
|
b01d242cbc | ||
|
|
cfd25b0a8d | ||
|
|
2f08c07c20 | ||
|
|
fd5e02c1f4 | ||
|
|
a549edb174 | ||
|
|
1c8f20440c | ||
|
|
5fb09c1c4a | ||
|
|
b7260ed982 | ||
|
|
aec0150a26 | ||
|
|
5c5dfcac89 | ||
|
|
32b9611eb5 | ||
|
|
12881db9ef | ||
|
|
bb8508abbd | ||
|
|
d6565bd2d9 | ||
|
|
b4633efcba | ||
|
|
0a003359ea | ||
|
|
c7e74774de | ||
|
|
dfefd0452d | ||
|
|
38d69c9e6f | ||
|
|
ac26df6827 | ||
|
|
99787950a8 | ||
|
|
80723496d0 | ||
|
|
ec440f13b1 | ||
|
|
8a9c7e54e2 | ||
|
|
67ca25cec4 | ||
|
|
4ca7b2e023 | ||
|
|
aea8b55e82 | ||
|
|
55a4b0ad1b | ||
|
|
f4124db320 | ||
|
|
e23e5a292d | ||
|
|
1f702c20ae | ||
|
|
9b1b915925 | ||
|
|
11bfefcd04 | ||
|
|
fceefac0ee | ||
|
|
98375f8629 | ||
|
|
d4e0cf7e18 | ||
|
|
62af066234 | ||
|
|
00d368080b | ||
|
|
e43b0d1522 | ||
|
|
400b14cd75 | ||
|
|
f88655e214 | ||
|
|
fc74a000a6 | ||
|
|
eb1a86e5b2 | ||
|
|
2fa3570f85 | ||
|
|
da2cf2acc5 | ||
|
|
f68ffefaa9 | ||
|
|
617fbdf8f7 | ||
|
|
034abb06ad | ||
|
|
46b176fc59 | ||
|
|
506686b11e | ||
|
|
1314cf1c19 | ||
|
|
f1e314fa13 | ||
|
|
3bce7de015 | ||
|
|
1bd035e1ca | ||
|
|
3a9ad5adb8 | ||
|
|
022d5bbd7d | ||
|
|
c905489ea5 | ||
|
|
65377d9236 | ||
|
|
8ead6c59c0 | ||
|
|
ea4e8856c2 | ||
|
|
318cfb5fe2 | ||
|
|
7706126479 | ||
|
|
ba84d0ead3 | ||
|
|
5604c6ece5 | ||
|
|
140f2970c4 | ||
|
|
b2ac98d25e | ||
|
|
1ed37897d5 | ||
|
|
29df3d658b | ||
|
|
576397a042 | ||
|
|
b7c9b84449 | ||
|
|
efbf799218 | ||
|
|
7d578ce363 | ||
|
|
e03e584684 | ||
|
|
e8e6b928cf | ||
|
|
5f6d29a3f8 | ||
|
|
a27d83a5e3 | ||
|
|
ef1154d6f3 | ||
|
|
ae2400fd0b | ||
|
|
fbcd004b7e | ||
|
|
cb307f95ce | ||
|
|
7838cd1a6a | ||
|
|
03dcb7d860 | ||
|
|
62c5470efe | ||
|
|
53b4674da4 | ||
|
|
ff2cf68b08 | ||
|
|
8b55373794 | ||
|
|
dba67d7127 | ||
|
|
762c455b53 | ||
|
|
714d1a36c4 | ||
|
|
0e0ddbbd99 | ||
|
|
497f8cfd1f | ||
|
|
1ff709e6f8 | ||
|
|
ea35871aba | ||
|
|
0e78857645 | ||
|
|
5d7d115910 | ||
|
|
b9384afd5d | ||
|
|
dbe020dc94 | ||
|
|
9673aa7690 | ||
|
|
ec06d30d59 | ||
|
|
356d2e592b | ||
|
|
521c2e7ca6 | ||
|
|
c4014c9333 | ||
|
|
2908a8d8a9 | ||
|
|
c964b98240 | ||
|
|
f7c74b5c96 | ||
|
|
d34c9818b4 | ||
|
|
6414c93116 | ||
|
|
5a12c4a3ce | ||
|
|
97a6ee39e5 | ||
|
|
44db5ab150 | ||
|
|
e9bcd29e36 | ||
|
|
a2ca897fca | ||
|
|
9a34e63d5f | ||
|
|
e501b894c3 | ||
|
|
d97ef84b7e | ||
|
|
0f2dc4d3ba | ||
|
|
49a9eb5460 | ||
|
|
7e7780a754 | ||
|
|
d0770970f0 | ||
|
|
d5a10a5817 | ||
|
|
7b63d8b2ba | ||
|
|
c544de8909 | ||
|
|
89da2ab50f | ||
|
|
a1a6b5967b | ||
|
|
53ffb1b565 | ||
|
|
6efecd123f | ||
|
|
1ec5349a96 | ||
|
|
187abcd10c | ||
|
|
d6ca4429d5 | ||
|
|
86e869ff16 | ||
|
|
dc58f9397f | ||
|
|
97b4ab2f15 | ||
|
|
23a9d02aba | ||
|
|
32ed6c3e97 | ||
|
|
102556dd2a | ||
|
|
2df3f7c56d | ||
|
|
d6fd02ec19 | ||
|
|
c901b4bc06 | ||
|
|
e19c89ccd9 | ||
|
|
a667f1a65e | ||
|
|
9f5829876c | ||
|
|
189d7c4719 | ||
|
|
dfe877c438 | ||
|
|
3a634d7888 | ||
|
|
fd9f3d04d9 | ||
|
|
ac70fc37f6 | ||
|
|
c29aeeee41 | ||
|
|
51c13c7b52 | ||
|
|
fec8c0fe53 | ||
|
|
5da2143212 | ||
|
|
30158ac145 | ||
|
|
ff7eecee55 | ||
|
|
0755a4026a | ||
|
|
9aaf363584 | ||
|
|
0a27cd7403 | ||
|
|
ab8cdd88b9 | ||
|
|
dab4a092d9 | ||
|
|
9d365dbf1e | ||
|
|
16d25fb60d | ||
|
|
50d43a2fc5 | ||
|
|
6d99539730 | ||
|
|
cf43dc8e70 | ||
|
|
95c506c638 | ||
|
|
464b768c55 | ||
|
|
00ca4cc5bd | ||
|
|
bfb81ef60d | ||
|
|
420701bf23 | ||
|
|
88073aaa20 | ||
|
|
8456320884 |
63
.gitattributes
vendored
@@ -1,63 +0,0 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
14
.gitignore
vendored
@@ -2,17 +2,11 @@
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
WebFirst/SoEasyPlatform.exe
|
||||
WebFirst/excel
|
||||
WebFirst/wwwroot
|
||||
WebFirst/SoEasyPlatform.exe
|
||||
WebFirst/appsettings.Development.json
|
||||
WebFirst/appsettings.json
|
||||
WebFirst/SoEasyPlatform.pdb
|
||||
WebFirst/SoEasyPlatform.Views.pdb
|
||||
WebFirst/web.config
|
||||
WebFirst/WebFirst.exe
|
||||
dist/
|
||||
|
||||
appsettings.Production.json
|
||||
appsettings.Development.json
|
||||
wwwroot
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
|
||||
214
LICENSE
@@ -1,201 +1,21 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
MIT License
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Copyright (c) 2022 jacktang
|
||||
|
||||
1. Definitions.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
347
README.md
@@ -1,7 +1,6 @@
|
||||
|
||||
|
||||
<h1 align="center"><img align="left" height="100px" src="https://user-images.githubusercontent.com/68722157/138828506-f58b7c57-5e10-4178-8f7d-5d5e12050113.png"> Yi框架</h1>
|
||||
<h4 align="center">一套与SqlSugar一样爽的.Net6开源框架</h4>
|
||||
<h1 align="center"><img align="left" height="150px" src="https://user-images.githubusercontent.com/68722157/138828506-f58b7c57-5e10-4178-8f7d-5d5e12050113.png"> Yi框架</h1>
|
||||
<h4 align="center">一套以用户体验出发的.Net6 Web开源框架</h4>
|
||||
<h5 align="center">支持原生版本、Furion版本、Abp版本,前端后台接入Ruoyi Vue3.0</h5>
|
||||
<h2 align="center">集大成者,终究轮子</h2>
|
||||
|
||||
[English](README-en.md) | 简体中文
|
||||
@@ -14,201 +13,241 @@
|
||||
|
||||
模块分化较多,可根据业务自行引用或抛弃,集大成者,大而全乎,也许你能从中学习到一些独特见解
|
||||
|
||||
正在持续更进业务模块,已接入ruoyi
|
||||
|
||||
**英文:YiFramework**
|
||||
|
||||
Yi框架-一套与SqlSugar一样爽的.Net6低代码开源框架。
|
||||
Yi框架-一套与SqlSugar一样爽的.Net6开源框架。
|
||||
与Sqlsugar理念一致,以用户体验出发。
|
||||
架构干净整洁、无业务代码、采用微软风格原生框架封装、WebFrist开发。
|
||||
适合.Net6学习、Sqlsugar学习 、项目二次开发。
|
||||
集大成者,终究轮子
|
||||
|
||||
Yi框架最新版本标签:`v1.2.0`,具体版本可以查看标签迭代
|
||||
Yi框架最新版本标签:`v3.0.0`,具体版本可以查看标签迭代
|
||||
|
||||
(项目与Sqlsugar同步更新,但这作者老杰哥代码天天爆肝到凌晨两点,我们也尽量会跟上他的脚步。更新频繁,所以可watching持续关注。)
|
||||
|
||||
————这不仅仅是一个程序,更是一个艺术品,面向艺术的开发!
|
||||
|
||||
**分支**:
|
||||
> 核心特点:简单好用,框架不以打包形式引用,而是直接以项目附带源码给出,自由度拉满,遵循Mit协议,允许随意修改(请注明来源即可)
|
||||
|
||||
(本项目由EFCore版本历经3年不断迭代至Sqlsugar版本,现EFcore版本已弃用,目前sqlsugar已带业务功能)
|
||||
**分支:**
|
||||
|
||||
**SqlSugar**:.Net6 DDD领域驱动设计 简单分层微服务架构
|
||||
(本项目由EFCore版本历经4年不断迭代至Sqlsugar版本,现EFcore版本已弃用,目前sqlsugar已带业务功能)
|
||||
|
||||
- Yi.Framework.Net6:.NetCore 6 意框架
|
||||
- (推荐) **Furion**: 基于Furion分支,回归开发本质,极度简单,用起来贼爽
|
||||
|
||||
- Yi.Vue3.X.RuoYi:Vue3 RuoYi前端框架
|
||||
- ~~**Framework**~~: 框架分支,所有东西都在这里
|
||||
|
||||
(你没有听错,已经接入java流行指数最高最火爆的框架之一,与其他框架不同,Yi框架后端为完全重制版,并非为ruoyi java模仿版)
|
||||
- ~~**SqlSugar**:.Net6 DDD领域驱动设计 简单分层微服务架构~~
|
||||
|
||||
**SqlSugar-Dev**:为sqlsugar分支的实时开发版本
|
||||
- ~~**SqlSugar-Dev**:为sqlsugar分支的实时开发版本~~
|
||||
|
||||
~~**ec**: EFcore完整电商项目~~
|
||||
- ~~**abp**:基于abp.vnext项目~~
|
||||
|
||||
****
|
||||
|
||||
**目录:**
|
||||
|
||||
Yi后端框架分为3个部分:
|
||||
|
||||
- Infrastructure(基础设施,框架底层+sqlsugar+furion)
|
||||
- Module(应用模块,可选项,例如缓存模块、微信模块、文件模块、日志模块等)
|
||||
- Application(业务模块,用于开发)
|
||||
|
||||
另外,光说不练假把式,我们不仅仅提供一个空白的框架,还同时提供3个基于yi框架的业务模块,没有听错,目前为1个后端,支持3个前端。各个模块关系解耦,可单独使用其中的任意业务模块
|
||||
|
||||
- Yi.RuoYi.Vue3:Ruoyi后台管理系统Rbac Vue3前端(推荐)
|
||||
|
||||
- Yi.Furion.Net6:.NET6后端(推荐)
|
||||
|
||||
- Yi.App.Vue3:移动端App Vue3前端
|
||||
|
||||
- Yi.BBS.Vue3:Web网页端BBS论坛 Vue3+Ts前端
|
||||
|
||||
后续我们持续更新各大应用模块及业务模块:shop商场、erp进销存、mes工厂系统等
|
||||
|
||||
业务支持并扩展至各个领域,用于具体项目的二次开发极大复用后端代码及前端代码,以通用的部分+不通的部分快速二开
|
||||
|
||||
|
||||
### 演示地址:
|
||||
|
||||
废话少说直接上地址,**请不要**更改里面的数据
|
||||
|
||||
API服务:~~[yi.ccnetcore.com](http://yi.ccnetcore.com) 管理员账号:admin 、 123~~
|
||||
官网网址:[ccnetcore.com](https://ccnetcore.com) (已上线,欢迎加入)
|
||||
|
||||
网关地址:~~[gate.ccnetcore.com/swagger](http://gate.ccnetcore.com/swagger)~~
|
||||
Bbs社区系统:[ccnetcore.com](https://ccnetcore.com) (已上线,欢迎加入)
|
||||
|
||||
WebFirst开发:所有代码生成器已经配置完成,无需任何操作数据库及任何代码,只需要网页表格上点点点即可
|
||||
Rbac后台管理系统:[yi.ccnetcore.com](http://yi.ccnetcore.com) (已上线)~~管理员账号:cc 、 123456~~
|
||||
|
||||
[https://www.donet5.com/Doc/11](https://www.donet5.com/Doc/11)
|
||||
App移动端系统:[xxx](xxx)正在部署
|
||||
|
||||
谁能把持的住Sqlsugar作者自己都依赖成瘾的东西呢?这是继DbFirst、CodeFirst下一代的划时代产品!无脑爽!
|
||||
|
||||

|
||||
|
||||
(首次添加实体后,生成代码记得修改对应的路径哦~~)
|
||||
网关地址:~~[gate.ccnetcore.com/swagger](http://gate.ccnetcore.com/swagger)~~(目前使用单体架构部署,无需网关)
|
||||
|
||||
### 支持:
|
||||
|
||||
- [x] 完全支持单体应用架构
|
||||
- [x] 完全支持分布式应用架构
|
||||
- [x] 完全支持微服务架构
|
||||
- [ ] 即将支持网格服务架构(我们将在后续版本加入dapr)
|
||||
|
||||
****
|
||||
### 软件架构:
|
||||
### 详细到爆炸的Yi框架教程导航:
|
||||
|
||||
**架构**:后端.NET6(Asp.NetCore 6)、WebFirst代码生成器~~与.NET5(Asp.NetCore 5)、前端Vue(2.0)~~
|
||||
|
||||
**关系型数据库**:mysql、sql server、sqlite、oracle(正在兼容中)
|
||||
|
||||
**操作系统**:Windows、Linux
|
||||
|
||||
**身份验证**:JWT、IdentityServer4
|
||||
|
||||
**组件**:SqlSugar、Autofac、Castle、Swagger、Log4Net、Redis、RabbitMq、ES、Quartz.net、~~T4~~
|
||||
|
||||
**分布式**:CAP、Lock
|
||||
|
||||
**微服务**:Consul、Ocelot、IdentityService、Apollo、Docker、Jenkins、Nginx、K8s、ELK、Polly
|
||||
|
||||
**封装**:Json处理模块,滑动验证码模块,base64图片处理模块,异常捕捉模块、邮件处理模块、linq封装模块、随机数模块、统一接口模块、基于策略的jwt验证、过滤器、数据库连接、跨域、初始化种子数据、Base32、Console输出、日期处理、文件传输、html筛选、http请求、ip过滤、md5加密、Rsa加密、序列化、雪花算法、字符串处理、编码处理、地址处理、xml处理、心跳检查。。。
|
||||
1. [框架快速开始](https://ccnetcore.com/article/1641733850189139969)(已完成)
|
||||
2. [框架模块教程](https://ccnetcore.com/article/1641733991574933505)(已完成)
|
||||
3. [应用模块教程](https://ccnetcore.com/article/1641734073091231745)
|
||||
4. [Yi.RBAC后台系统](https://ccnetcore.com/article/1641734171128893441)
|
||||
5. [Yi.BBS社区系统](https://ccnetcore.com/article/1641734308475572225)
|
||||
|
||||
****
|
||||
<h3>业务支持模块</h3>
|
||||
### 它的理念:
|
||||
优雅的进行快速开发,通常,简单程度与优雅程度不可兼得,Yi框架并不一昧的追求极致的解耦,会站在用户使用角度上,在使用难易度进行考虑衡量
|
||||
|
||||
(大部分ruoyi功能,采用ruoyi前端)
|
||||
例如:我们大部分功能紧密贴合Sqlsugar,虽然缺少其他orm的替换性,但在使用程度上降低的使用难度
|
||||
|
||||
- 用户管理
|
||||
> 一个面向用户的快速开发后端框架
|
||||
|
||||
- 角色管理
|
||||
|
||||
- 菜单管理
|
||||
|
||||
- 部门管理
|
||||
|
||||
- 岗位管理
|
||||
|
||||
- 字典管理
|
||||
|
||||
- 参数管理
|
||||
|
||||
- 用户在线
|
||||
|
||||
- 操作日志
|
||||
|
||||
- 登录日志
|
||||
在真正的使用这,你会明白这一点,极致的简单,也是优雅的一种体现。
|
||||
****
|
||||
|
||||
### 特点:
|
||||
- 面向用户的后端框架,使用简单,适合小型、企业级项目
|
||||
- 项目内置源码,不打包
|
||||
- 开箱即用
|
||||
- 支持模块化
|
||||
- 支持动态Api
|
||||
- 支持属性注入
|
||||
- 内置包含大量通用场景模块
|
||||
- 等等
|
||||
|
||||

|
||||
### 基础设施简介
|
||||
- Jwt鉴权
|
||||
- 接口级别授权
|
||||
- 对象映射
|
||||
- O/RM
|
||||
- 数据过滤
|
||||
- 多租户
|
||||
- 逻辑删除
|
||||
- 审计日志
|
||||
- 种子数据
|
||||
- 工作单元
|
||||
- 模块化
|
||||
- 动态Api
|
||||
- 属性注入
|
||||
- 自动依赖注入
|
||||
- 当前用户
|
||||
- 仓储
|
||||
- Crud
|
||||
|
||||

|
||||
|
||||
### 框架支持模块:
|
||||
### 内置模块简介
|
||||
- 后台任务
|
||||
- 本地缓存
|
||||
- 分布式缓存
|
||||
- 事件总线
|
||||
- 字典管理
|
||||
- 文件管理
|
||||
- 图片操作
|
||||
- Excel操作
|
||||
- 操作日志管理
|
||||
- Sms短信
|
||||
- 微信支付
|
||||
- WebFirst代码生成
|
||||
|
||||
大致如图:
|
||||
### 业务项目
|
||||
- RABC后台管理系统
|
||||
- BBS社区系统
|
||||
- APP移动端系统
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
(删除线代表已实现功能还未迁移过来)
|
||||
- [x] 支持大致`DDD领域驱动设计`进行分层,支持微服务扩展
|
||||
- [x] 支持采用`异步`开发awit/async
|
||||
- [x] 支持数据库主从`读写分离`
|
||||
- [x] 支持功能替换,无需改动代码,只需配置`json文件`进行装配即可
|
||||
- [x] 支持WebFirst,无需改动代码,自动生成全套代码与数据库,只需点点点
|
||||
- [x] 支持`用户-角色-菜单-接口`以及vue2.0前端全部逻辑代码,下载无需修改直接使用
|
||||
- [x] 支持`Aop封装`,FilterAop、IocAop、LogAop、SqlAop
|
||||
- [x] 支持`Log4Net日志`记录,自动生成至bin目录下的logs文件夹
|
||||
- [x] 支持`DbSeed数据库种子数据`接入
|
||||
- [x] 支持主流`数据库随意切换`,Mysql/Sqlite/Sqlserver/Oracle
|
||||
- [x] 支持上海杰哥官方`SqlSugar ORM`封装
|
||||
- [x] 支持新版`SwaggerWebAPI`,jwt身份认证接入
|
||||
- [x] 支持`Cors`跨域
|
||||
- [x] 支持`AutoFac`自动映射依赖注入
|
||||
- [x] 支持`consul`服务器注册与发现
|
||||
- [x] 支持`健康检查`
|
||||
- [x] 支持`RabbitMQ`消息队列
|
||||
- [x] 支持`Redis`多级缓存
|
||||
- [x] 支持`Ocelot`网关,路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递
|
||||
- [x] 支持`Apollo`全局配置中心;
|
||||
- [x] 支持`docker`镜像制作
|
||||
- [x] 支持`Quartz.net`任务调度,实现任意接口被调度
|
||||
- [x] 支持`ELK`,log4net+kafka+es+logstach+kibana
|
||||
- [x] 支持`IdentityService4`授权中心
|
||||
- [x] 支持`Es`分词查询
|
||||
- [x] 支持多级`缓存`
|
||||
- [x] 支持`CAP`分布式事务,mysql+rabbitMq
|
||||
- [x] 支持`Docker+k8s`部署
|
||||
- [x] 支持`Jenkins+CI/CD`
|
||||
- [x] 支持`AutoMapper`模块映射
|
||||
- [x] 支持`微信支付`
|
||||
- [x] 支持`单表多租户`常用功能
|
||||
- [x] 支持`逻辑删除`常用功能
|
||||
- [x] 支持`操作日志`常用功能
|
||||
- [x] 支持`自动分表`
|
||||
- [x] 支持 太多了忘了
|
||||
> 重复的东西,无需再写一遍,这也是优雅的体现之一
|
||||
|
||||
****
|
||||
### 目录结构:
|
||||
### 核心技术
|
||||
#### 后端
|
||||
C# Asp.NetCore 6.0
|
||||
- [x] 动态Api:Cike.AutoApi
|
||||
- [x] 鉴权授权:Jwt
|
||||
- [x] 日志:Nlog
|
||||
- [x] 模块化:StartupModules
|
||||
- [x] 依赖注入:Autofac
|
||||
- [x] 对象映射:Mapster
|
||||
- [x] ORM:SqlsugarCore
|
||||
- [x] 多租户:Abp
|
||||
- [x] 后台任务:Quartz.Net
|
||||
- [x] 本地缓存:MemortCache
|
||||
- [x] 分布式缓存:CSRedisCore
|
||||
- [x] 事件总线:Cike.EventBus
|
||||
- [x] 图像操作:SixLabors.ImageSharp
|
||||
- [x] Excle操作:ExcelToObject.Npoi
|
||||
|
||||

|
||||

|
||||

|
||||
#### 前端
|
||||
js Vue3.2
|
||||
- [x] 异步请求:axios
|
||||
- [x] 图表:echarts
|
||||
- [x] ui:element-plus
|
||||
- [x] 存储:pinia
|
||||
- [x] 路由:vue-router
|
||||
- [x] 打包:vite
|
||||
|
||||
我们大致依照DDD领域驱动设计分层
|
||||
|
||||
分层如此清晰!什么?还感觉太复杂了?用户只需关注Api、Service其他都是轮子啊!
|
||||
|
||||
~~- BackGround:后台进程(目前可以无视,等待更新)~~
|
||||
- Client:客户端(测试、客户端)
|
||||
- Domain:领域层(Dto、服务接口层、模型层、仓储层、服务层)
|
||||
- Infrastructure:基础实例层(通用工具层、核心层、定时任务Job、国际化、Web扩展层)
|
||||
- MicroServiceInstance:服务层(微服务)
|
||||
#### 运维
|
||||
- [x] 部署:nginx
|
||||
- [x] CICD:gitlab+Jenkins
|
||||
- [x] Docker:harbor
|
||||
|
||||
****
|
||||
### 安装教程:
|
||||
### 业务支持模块:
|
||||
|
||||
我们将在之后更新教程手册!
|
||||
RABC权限管理系统(正在更新)
|
||||
(采用ruoyi前端)
|
||||
- 用户管理
|
||||
- 角色管理
|
||||
- 菜单管理
|
||||
- 部门管理
|
||||
- 岗位管理
|
||||
- 字典管理
|
||||
- 参数管理
|
||||
- 用户在线
|
||||
- 操作日志
|
||||
- 登录日志
|
||||
- 定时任务
|
||||
- 缓存列表
|
||||
- 服务监控
|
||||
- WebFirst代码生成工具
|
||||
|
||||
1. 下载全部源码,默认使用sqlite数据库,已经生成
|
||||
2. 直接点击sln文件运行即可,没有其他依赖
|
||||
**演示截图:**
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
****
|
||||
### 使用说明:
|
||||
BBS论坛系统(持续迭代)
|
||||
- 文章管理
|
||||
- 评论管理
|
||||
- 主题管理
|
||||
- 板块管理
|
||||
- 点赞管理
|
||||
- 等等
|
||||
|
||||
1. 导入使用仓库中的WebFirst数据库
|
||||
2. 使用WebFirst添加实体、同步实体、修改模板生成路径并生成方案
|
||||
APP移动端系统(持续迭代)
|
||||
- 动态查询
|
||||
- 我的资料
|
||||
|
||||
没了,恭喜你已经成功完成了项目,并且已经具备大部分通用场景业务
|
||||
是不是一个字?爽!
|
||||
到此为止,你无需写任何一个代码!
|
||||
ERP进销存系统(持续迭代)
|
||||
- 供货商管理
|
||||
- 等等
|
||||
|
||||
**爽点**:
|
||||
SHOP电商系统(持续迭代)
|
||||
- SPU管理
|
||||
- SKU管理
|
||||
- 商品规格
|
||||
- 商品分类
|
||||
- 等等
|
||||
|
||||
新人,看这里,项目下载之后直接可以启动,无任何依赖,之后你可以查看`Test控制器`,迫不及待的快来爽一爽!
|
||||
|
||||
我们将使用说明转移至我们的官方论坛中,正在制作中,尽情期待!
|
||||
|
||||
****
|
||||
### 感谢:
|
||||
@@ -221,44 +260,30 @@ WebFirst开发:所有代码生成器已经配置完成,无需任何操作数
|
||||
|
||||
[朝夕教育]https://www.zhaoxiedu.net
|
||||
|
||||
[Sqlsugar]https://www.donet5.com/Home/Doc
|
||||
[Sqlsugar老杰哥]https://www.donet5.com/Home/Doc
|
||||
|
||||
[RuYiAdmin]https://gitee.com/pang-mingjun/RuYiAdmin
|
||||
[RuYiAdmin如意老兄]https://gitee.com/pang-mingjun/RuYiAdmin
|
||||
|
||||
[ZrAdminNetCore]https://gitee.com/izory/ZrAdminNetCore
|
||||
[ZrAdminNetCore字母老哥]https://gitee.com/izory/ZrAdminNetCore
|
||||
|
||||
[Admin.NET周哥]https://gitee.com/zuohuaijun/Admin.NET
|
||||
|
||||
[Furion百小僧]https://furion.baiqian.ltd/
|
||||
|
||||
****
|
||||
### 联系我们:
|
||||
|
||||
作者QQ:`454313500`,2029年之前作者24小时在线,时刻保持活跃更新。
|
||||
|
||||
QQ交流群:官方一群(已满)、官方二群(已满)、官方三群:`786308927`(加作者QQ后同意)
|
||||
QQ交流群:官方一群(已满)、官方二群(已满)、官方三群:`786308927`(基本已满)、官方四群:`498310311`(新群)
|
||||
|
||||
联系作者,这里人人都是顾问
|
||||
|
||||
官方网址:正在建设
|
||||
官方网址留言区:[ccnetcore.com](https://ccnetcore.com)
|
||||
|
||||
****
|
||||
### FQA:
|
||||
|
||||
问1:为什么不采用EFcore?
|
||||
前往官网查看留言区
|
||||
|
||||
答1:别问,问就是Sqlsugar,和本框架一样爽!
|
||||
|
||||
问2:以后会持续更新下去吗?
|
||||
|
||||
答2:一定会的,我们的标题是 一个和Sqlsugar一样爽的.Net6开源框架 ,只要Sqlsugar在,我们将一直更新下去。
|
||||
|
||||
问3:这个框架的针对人群是哪些人?适合所有人吗?
|
||||
|
||||
答3:并不是适合所有人,应该算适合需要有一定基础的开发人员,当然,如果你是大神,你完全可以将这个框架二次开发!
|
||||
|
||||
问4:花如此多的精力制作这个框架,是为了什么?是为了赚钱吗?和目前主流的abp等框架比,又有什么意义呢?
|
||||
|
||||
答4:我们与Sqlsugar作者理念一致,我们是从用户角度出发,框架是为用户服务,与ABP复杂上手理念完全是相反的。
|
||||
|
||||
问5:为何不出版一个详细的说明书呢?
|
||||
|
||||
答5:暂时不会了,之后可能会,代码都是基于Asp.NetCore框架,适用于新手不用造轮子,整个框架较为简单,阅读源码后,基本能自定义改造使用了,过难也已经封装完毕,别忘了,其意义是为了开发更加简易!建议添加作者好友,这里人人都是顾问。
|
||||
|
||||
我大抵要厌倦了负重前行。
|
||||
[留言区](https://ccnetcore.com/discuss/1641030787056930818)
|
||||
BIN
Readme/用户管理.png
|
Before Width: | Height: | Size: 79 KiB |
BIN
Readme/菜单管理.png
|
Before Width: | Height: | Size: 153 KiB |
0
Yi.App.Vue3/components.d.ts
vendored
Normal file
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Vite + Vue + TS</title>
|
||||
<title>意框架</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
@@ -30,10 +30,7 @@
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.5.2.tgz",
|
||||
"integrity": "sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.19.3",
|
||||
@@ -430,12 +427,6 @@
|
||||
"resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
@@ -896,12 +887,6 @@
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
@@ -987,9 +972,6 @@
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
@@ -1037,9 +1019,6 @@
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
@@ -1159,9 +1138,6 @@
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
@@ -1172,9 +1148,6 @@
|
||||
"@vue/devtools-api": "^6.4.4",
|
||||
"vue-demi": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.4.0",
|
||||
"typescript": ">=4.4.4",
|
||||
@@ -1201,9 +1174,6 @@
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
@@ -1218,16 +1188,6 @@
|
||||
"version": "8.4.17",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.17.tgz",
|
||||
"integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.4",
|
||||
"picocolors": "^1.0.0",
|
||||
@@ -1246,21 +1206,7 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
@@ -1286,9 +1232,6 @@
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
@@ -1321,20 +1264,6 @@
|
||||
"resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
@@ -1373,7 +1302,8 @@
|
||||
"node_modules/sourcemap-codec": {
|
||||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
|
||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||
"deprecated": "Please use @jridgewell/sourcemap-codec instead"
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
@@ -1382,9 +1312,6 @@
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
@@ -1444,9 +1371,6 @@
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/parser": "^7.15.8",
|
||||
"vue": "2 || 3"
|
||||
@@ -1542,9 +1466,6 @@
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.1.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
11
Yi.App.Vue3/src/api/agreeApi.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
operate(data:any) {
|
||||
return myaxios({
|
||||
url: `/agree/operate`,
|
||||
method: 'get',
|
||||
params: {articleId:data}
|
||||
})
|
||||
},
|
||||
}
|
||||
18
Yi.App.Vue3/src/api/articleApi.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data:any) {
|
||||
return myaxios({
|
||||
url: `/Trends`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data:any) {
|
||||
return myaxios({
|
||||
url: '/Trends',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
}
|
||||
17
Yi.App.Vue3/src/api/commentApi.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data:any) {
|
||||
return myaxios({
|
||||
url: `/comment/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
getListByArticleId(articleId:any) {
|
||||
return myaxios({
|
||||
url: `/comment/GetListByArticleId/${articleId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import myaxios from '@/utils/myaxios.ts'
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default{
|
||||
upload(type:string,data:any){
|
||||
upload(data:any){
|
||||
return myaxios({
|
||||
url: `/file/upload/${type}`,
|
||||
url: `/file`,
|
||||
headers:{"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"},
|
||||
method: 'POST',
|
||||
method: 'post',
|
||||
data:data
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import myaxios from '@/utils/myaxios.ts'
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
// 登录方法
|
||||
export function login(username:string, password:string, code:string, uuid:string) {
|
||||
@@ -33,7 +33,7 @@ export function register(data:any) {
|
||||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
return myaxios({
|
||||
url: '/account/getUserAllInfo',
|
||||
url: '/account',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
18
Yi.App.Vue3/src/api/skuApi.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data:any) {
|
||||
return myaxios({
|
||||
url: `/sku/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data:any) {
|
||||
return myaxios({
|
||||
url: '/sku/pageList',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
}
|
||||
25
Yi.App.Vue3/src/api/spuApi.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import myaxios from '@/utils/myaxios'
|
||||
|
||||
export default {
|
||||
add(data: any) {
|
||||
return myaxios({
|
||||
url: `/spu/add`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
pageList(data: any) {
|
||||
return myaxios({
|
||||
url: '/spu/pageList',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
getById(id: any) {
|
||||
return myaxios({
|
||||
url: `/spu/GetById/${id}`,
|
||||
method: 'get',
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 496 B After Width: | Height: | Size: 496 B |
61
Yi.App.Vue3/src/components/AppCard.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
|
||||
<div class="out-div">
|
||||
<div class="card-div">
|
||||
|
||||
<van-image
|
||||
radius="1rem"
|
||||
width="100%"
|
||||
height="100%"
|
||||
src="https://unpkg.com/@vant/assets/cat.jpeg"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="bottom-div">
|
||||
<div v-for="i of 10" :key="i" class="card-div-inside">
|
||||
<van-image
|
||||
radius="1rem"
|
||||
width="4rem"
|
||||
height="4rem"
|
||||
src="https://unpkg.com/@vant/assets/cat.jpeg"
|
||||
/>
|
||||
<br>
|
||||
¥79.0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.out-div {
|
||||
width: 100%;
|
||||
min-height: 10rem;
|
||||
border-radius: 1rem;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.card-div {
|
||||
height: 6rem;
|
||||
width: 100%;
|
||||
}
|
||||
.bottom-div {
|
||||
display: flex;
|
||||
|
||||
/* justify-content: center; */
|
||||
width: 100%;
|
||||
height: 6rem;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-div-inside {
|
||||
flex: none;
|
||||
display: block;
|
||||
margin-top: 0.5rem;
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import {AppGridData} from '@/type/class/AppGridData.ts'
|
||||
import {AppGridData} from '@/type/class/AppGridData'
|
||||
defineProps<{ data: AppGridData }>()
|
||||
const count = ref(0)
|
||||
</script>
|
||||
@@ -17,10 +17,13 @@ const count = ref(0)
|
||||
.col-body
|
||||
{
|
||||
text-align: center;
|
||||
|
||||
font-size: small;
|
||||
}
|
||||
.col-body .van-icon
|
||||
{
|
||||
|
||||
color: #FF689B;
|
||||
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
p{
|
||||
35
Yi.App.Vue3/src/components/AppUserIcon.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<van-image round :width="width" :height="height" :src="getUrl()" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
src: { type: String, default: "null", required: false },
|
||||
width: { type: String, default: "3rem", required: false },
|
||||
height: { type: String, default: "3rem", required: false },
|
||||
});
|
||||
|
||||
const url = `${import.meta.env.VITE_APP_BASE_API}/file/`;
|
||||
const getUrl = () => {
|
||||
const src = props.src;
|
||||
if (src === null || typeof src === "undefined" || src.trim() === "") {
|
||||
return "/icon.jpg";
|
||||
|
||||
// 字符串为 null、未定义或为空字符串
|
||||
} else {
|
||||
return url + "src";
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.col-body {
|
||||
text-align: center;
|
||||
}
|
||||
.col-body .van-icon {
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
p {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
@@ -1,17 +1,14 @@
|
||||
<template>
|
||||
<van-tabbar v-model="active" active-color="#ee0a24" inactive-color="#000">
|
||||
<van-tabbar-item icon="home-o" to="/">主页</van-tabbar-item>
|
||||
<van-tabbar-item icon="search">发现</van-tabbar-item>
|
||||
|
||||
<van-tabbar v-model="active" active-color="#FF689B" inactive-color="#9C9C9C" @change="onChange" z-index="100">
|
||||
<van-tabbar-item v-for="item in tabbar.slice(0,2)" :to="item.to" :icon="item.icon">{{item.title}}</van-tabbar-item>
|
||||
<van-tabbar-item @click="show = true">
|
||||
<template #icon="props">
|
||||
<van-icon class="add" name="add-square" color="#1989fa" size="3rem" />
|
||||
<van-icon class="add" name="add-square" color="#FF689B" size="3rem" />
|
||||
<!-- <img :src="props.active ? icon.active : icon.inactive" /> -->
|
||||
</template>
|
||||
</van-tabbar-item>
|
||||
|
||||
<van-tabbar-item icon="friends-o">商城</van-tabbar-item>
|
||||
<van-tabbar-item icon="setting-o" to="/my">我的</van-tabbar-item>
|
||||
<van-tabbar-item v-for="item in tabbar.slice(3)" :to="item.to" :icon="item.icon">{{item.title}}</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
|
||||
<van-action-sheet v-model:show="show" >
|
||||
@@ -33,6 +30,27 @@
|
||||
import { ref } from 'vue'
|
||||
const active = ref(0);
|
||||
const show = ref(false);
|
||||
|
||||
let tabbar=ref([
|
||||
{icon:"wap-home",to:"/",title:"主页"},
|
||||
{icon:"location-o",to:"",title:"发现"},
|
||||
{icon:"",to:"",title:""},
|
||||
{icon:"friends-o",to:"/shopIndex",title:"商城"},
|
||||
// {icon:"friends-o",to:"",title:"商城"},
|
||||
{icon:"setting-o",to:"/my",title:"我的"},
|
||||
])
|
||||
const onChange=(index:number)=>{
|
||||
tabbar.value=[
|
||||
{icon:"wap-home-o",to:"/",title:"主页"},
|
||||
{icon:"location-o",to:"",title:"发现"},
|
||||
{icon:"",to:"",title:""},
|
||||
{icon:"friends-o",to:"/shopIndex",title:"商城"},
|
||||
// {icon:"friends-o",to:"",title:"商城"},
|
||||
{icon:"setting-o",to:"/my",title:"我的"},
|
||||
];
|
||||
tabbar.value[index].icon=tabbar.value[index].icon.replace("-o","")
|
||||
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.btn1
|
||||
9
Yi.App.Vue3/src/layout/head/index.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<van-nav-bar
|
||||
title="标题"
|
||||
left-text="返回"
|
||||
left-arrow
|
||||
/>
|
||||
<br>
|
||||
<router-view />
|
||||
</template>
|
||||
@@ -3,10 +3,8 @@
|
||||
<van-row class="row" >
|
||||
<van-col span="4" class="icon"><van-icon name="sign" size="1.6rem"/></van-col>
|
||||
<van-col span="16">
|
||||
<van-tabs v-model:active="active" class="tabs" sticky >
|
||||
<van-tab title="关注" to="/follow" class="tab" ></van-tab>
|
||||
<van-tab title="推荐" to="/recommend" class="tab" ></van-tab>
|
||||
<van-tab title="广场" to="/square" class="tab" ></van-tab>
|
||||
<van-tabs v-model:active="active" class="tabs" sticky swipeable color="#FF689B">
|
||||
<van-tab v-for="item in tabs" :title="item.title" :to="item.to" class="tab" :style="{fontSize: 0 + 'px'}" ></van-tab>
|
||||
</van-tabs>
|
||||
</van-col>
|
||||
<van-col span="4" class="icon"><van-icon name="search" size="1.6rem" /></van-col>
|
||||
@@ -20,6 +18,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
const active = ref(1);
|
||||
const tabs=ref([
|
||||
{title:"关注",to:"/follow"},
|
||||
{title:"推荐",to:"/recommend"},
|
||||
{title:"广场",to:"/square"},
|
||||
])
|
||||
</script>
|
||||
<style scoped>
|
||||
.row{
|
||||
@@ -35,4 +38,8 @@ const active = ref(1);
|
||||
.tabs {
|
||||
width: 100%;
|
||||
}
|
||||
.icon .van-icon
|
||||
{
|
||||
color:#FF689B;
|
||||
}
|
||||
</style>
|
||||
@@ -7,10 +7,11 @@ import 'vant/es/notify/style';
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import './permission'
|
||||
|
||||
import { Lazyload } from 'vant';
|
||||
import App from './App.vue'
|
||||
|
||||
const app=createApp(App)
|
||||
app.use(router)
|
||||
app.use(store)
|
||||
app.use(Lazyload);
|
||||
app.mount('#app');
|
||||
@@ -4,7 +4,7 @@ import router from './router'
|
||||
// import 'nprogress/nprogress.css'
|
||||
import { getToken } from '@/utils/auth'
|
||||
// import { isHttp } from '@/utils/validate'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useUserStore from '@/store/modules/user.js'
|
||||
import { isRelogin } from '@/utils/myaxios'
|
||||
// import useSettingsStore from '@/store/modules/settings'
|
||||
// import usePermissionStore from '@/store/modules/permission'
|
||||
@@ -1,14 +1,20 @@
|
||||
import { createWebHistory, createRouter } from 'vue-router';
|
||||
import Layout from '@/layout/index.vue';
|
||||
import HeadLayout from '@/layout/head/index.vue'
|
||||
|
||||
export const constantRoutes = [
|
||||
|
||||
|
||||
{
|
||||
name:'Layout',
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect:"/recommend",
|
||||
children: [
|
||||
{
|
||||
path: '/shopIndex',
|
||||
component: () => import('@/view/shop/shopIndex.vue'),
|
||||
name: 'ShopIndex',
|
||||
},
|
||||
{
|
||||
path: '/my',
|
||||
component: () => import('@/view/my.vue'),
|
||||
@@ -49,6 +55,25 @@ export const constantRoutes = [
|
||||
component: () => import('@/view/login.vue'),
|
||||
name: 'Login',
|
||||
},
|
||||
|
||||
{
|
||||
name:'Shop',
|
||||
path: '/shop',
|
||||
component: HeadLayout,
|
||||
redirect:"/shopIndex",
|
||||
children: [
|
||||
{
|
||||
path: '/shopDetails',
|
||||
component: () => import('@/view/shop/shopDetails.vue'),
|
||||
name: 'ShopDetails',
|
||||
},
|
||||
{
|
||||
path: '/shopSearch',
|
||||
component: () => import('@/view/shop/shopSearch.vue'),
|
||||
name: 'ShopSearch',
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
@@ -7,13 +7,13 @@ const useUserStore = defineStore(
|
||||
{
|
||||
state: () => ({
|
||||
token: getToken(),
|
||||
user:{username:"",nick:""},
|
||||
user:{username:"",nick:"",icon:""},
|
||||
roles: [],
|
||||
permissions: []
|
||||
}),
|
||||
actions: {
|
||||
// 登录
|
||||
login(userInfo) {
|
||||
login(userInfo:any ) {
|
||||
const username = userInfo.username.trim()
|
||||
const password = userInfo.password
|
||||
const code = userInfo.code
|
||||
@@ -21,22 +21,28 @@ const useUserStore = defineStore(
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
login(username, password, code, uuid).then(res => {
|
||||
if(!(res as any).succeeded)
|
||||
{
|
||||
reject(res)
|
||||
}
|
||||
setToken(res.data.token);
|
||||
this.token = res.data.token;
|
||||
resolve(res);
|
||||
|
||||
return resolve(res);
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
return reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
// 获取用户信息
|
||||
getInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
getInfo().then(response => {
|
||||
const res=response.data;
|
||||
const user = res.user
|
||||
// const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
|
||||
const avatar=""
|
||||
|
||||
if (res.roleCodes && res.roleCodes.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||
this.roles = res.roleCodes
|
||||
this.permissions = res.permissionCodes
|
||||
@@ -44,16 +50,16 @@ const useUserStore = defineStore(
|
||||
// this.permissions=["*:*:*"]
|
||||
|
||||
} else {
|
||||
this.roles = ['ROLE_DEFAULT']
|
||||
this.roles = ["ROLE_DEFAULT"] as never[]
|
||||
}
|
||||
// this.roles = ["admin"];
|
||||
// this.permissions=["*:*:*"]
|
||||
this.user.username = user.userName;
|
||||
this.user.nick=user.nick
|
||||
this.avatar = avatar;
|
||||
resolve(res)
|
||||
this.user.icon = user.icon;
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
reject(error)
|
||||
})
|
||||
|
||||
|
||||
@@ -63,7 +69,8 @@ const useUserStore = defineStore(
|
||||
// 退出系统
|
||||
logOut() {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(this.token).then((response) => {
|
||||
//this.token
|
||||
logout().then((response) => {
|
||||
this.token = ''
|
||||
this.roles = []
|
||||
this.permissions = []
|
||||
@@ -3,6 +3,6 @@ export interface ArticleEntity{
|
||||
content: string;
|
||||
images:string[];
|
||||
isDeleted:boolean;
|
||||
createTime:string;
|
||||
creationTime:string;
|
||||
}
|
||||
// import { ArticleEntity } from '@/type/interface/ArticleEntity'
|
||||
95
Yi.App.Vue3/src/utils/myaxios.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
import axios from 'axios'
|
||||
// import store from '../store/index'
|
||||
// import vm from '../main'
|
||||
import JsonBig from 'json-bigint'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { useRouter } from "vue-router";
|
||||
import useUserStore from '@/store/modules/user.js'
|
||||
import { Notify } from 'vant';
|
||||
// import VuetifyDialogPlugin from 'vuetify-dialog/nuxt/index';
|
||||
export let isRelogin = { show: false };
|
||||
const myaxios = axios.create({
|
||||
// baseURL:'/'//
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API, // /dev-apis
|
||||
timeout: 50000,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + ""
|
||||
},
|
||||
//雪花id精度问题
|
||||
transformResponse: [data => {
|
||||
const json = JsonBig({
|
||||
storeAsString: true
|
||||
});
|
||||
try {
|
||||
return json.parse(data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}],
|
||||
})
|
||||
// 请求拦截器
|
||||
myaxios.interceptors.request.use(function (config:any) {
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||
if (getToken() && !isToken) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
// store.dispatch("openLoad");
|
||||
return config;
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// 响应拦截器
|
||||
myaxios.interceptors.response.use(async function(response) {
|
||||
//成功
|
||||
const resp = response.data
|
||||
if(resp.code==401)
|
||||
{
|
||||
Notify({ type: 'warning', message: '登录过期' });
|
||||
//登出
|
||||
useUserStore().logOut().then(() => {
|
||||
location.href = '/';
|
||||
})
|
||||
isRelogin.show = false;
|
||||
}
|
||||
// store.dispatch("closeLoad");
|
||||
return resp;
|
||||
},
|
||||
async function(error) {
|
||||
const code=error.response.status;
|
||||
const message=error.message;
|
||||
//未授权、失败
|
||||
if(error.response==undefined)
|
||||
{
|
||||
Notify({ type: 'danger', message: `服务器异常:${error.message}` });
|
||||
|
||||
// useUserStore().logOut().then(() => {
|
||||
// location.href = '/';
|
||||
// })
|
||||
|
||||
return Promise.reject(error);;
|
||||
}
|
||||
|
||||
if (code == undefined &&message == undefined) {
|
||||
Notify({ type: 'danger', message: '未知错误' });
|
||||
} else if (code == 401) {
|
||||
// if (!isRelogin.show) {
|
||||
Notify({ type: 'warning', message: '登录过期' });
|
||||
//登出
|
||||
useUserStore().logOut().then(() => {
|
||||
location.href = '/';
|
||||
})
|
||||
isRelogin.show = false;
|
||||
// }
|
||||
} else if (code !== 200) {
|
||||
Notify({ type: 'danger', message: `错误代码:${code},原因:${message}` });
|
||||
}
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
export default myaxios
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="div-top">
|
||||
<span class="title">农夫山泉</span>
|
||||
<span class="title">意框架</span>
|
||||
<br />
|
||||
<span class="subtitle">农夫山泉有点甜</span>
|
||||
<span class="subtitle">有幸相遇、不负未来</span>
|
||||
</div>
|
||||
<div class="div-bottom">
|
||||
<h5>密码登录</h5>
|
||||
@@ -16,32 +16,35 @@
|
||||
class="van-field-password"
|
||||
v-model="loginForm.password"
|
||||
label="密码"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
/>
|
||||
<van-button type="primary" @click="login">进入农夫山泉</van-button>
|
||||
<van-button type="primary" @click="login">进入意框架</van-button>
|
||||
<p>其他方式登录<van-icon name="arrow" /></p>
|
||||
|
||||
<van-row style="margin-top: 6rem">
|
||||
<van-row class="row-bottom" style="margin-top: 6rem">
|
||||
<van-col span="24"><p>第三方登录</p></van-col>
|
||||
<van-col span="3"></van-col>
|
||||
<van-col span="6"><van-icon name="like" size="2rem" /></van-col>
|
||||
<van-col span="6"><van-icon name="like" size="2rem" /></van-col>
|
||||
<van-col span="6"><van-icon name="like" size="2rem" /></van-col>
|
||||
<van-col span="3"></van-col>
|
||||
<van-col span="2"></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="5"><van-icon name="smile-o" size="2rem" /></van-col>
|
||||
<van-col span="2"></van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import useUserStore from "@/store/modules/user.js";
|
||||
import { Toast } from "vant";
|
||||
import { debug } from "console";
|
||||
|
||||
const router = useRouter();
|
||||
const redirect = ref(undefined);
|
||||
const loginForm = ref({
|
||||
username: "cc",
|
||||
password: "123456",
|
||||
username: "",
|
||||
password: "",
|
||||
rememberMe: false,
|
||||
code: "",
|
||||
uuid: "",
|
||||
@@ -53,14 +56,16 @@ const login = () => {
|
||||
.login(loginForm.value)
|
||||
.then((response: any) => {
|
||||
Toast({
|
||||
message: response.message,
|
||||
message: "登录成功",
|
||||
position: "bottom",
|
||||
});
|
||||
|
||||
router.push({ path: redirect.value || "/" });
|
||||
})
|
||||
.catch((response:any) => {
|
||||
loginForm.value.password="";
|
||||
Toast({
|
||||
message: response.message,
|
||||
message: response.errors,
|
||||
position: "bottom",
|
||||
});
|
||||
// loading.value = false;
|
||||
@@ -73,7 +78,7 @@ const login = () => {
|
||||
</script>
|
||||
<style scoped>
|
||||
.div-top {
|
||||
background-color: aqua;
|
||||
background-color: #FF689B;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -81,7 +86,7 @@ const login = () => {
|
||||
bottom: 60%;
|
||||
}
|
||||
.div-bottom {
|
||||
background-color: bisque;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
left: 0;
|
||||
@@ -98,12 +103,14 @@ const login = () => {
|
||||
transform: translateX(-50%);
|
||||
font-size: 1.8rem;
|
||||
font-weight: bolder;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.subtitle {
|
||||
transform: translateX(-50%);
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
font-weight: lighter;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.van-field-username {
|
||||
margin-top: 2rem;
|
||||
@@ -113,17 +120,21 @@ const login = () => {
|
||||
}
|
||||
h5 {
|
||||
text-align: left;
|
||||
font-size: 1.2rem;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bolder;
|
||||
}
|
||||
.div-bottom .van-button {
|
||||
margin-top: 1rem;
|
||||
width: 100%;
|
||||
border-radius: 0.4rem;
|
||||
background-color: #FF689B;
|
||||
border: 0;
|
||||
}
|
||||
.div-bottom p {
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
}
|
||||
.row-bottom {
|
||||
color: #FF689B;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list
|
||||
class="list"
|
||||
v-model:loading="loading"
|
||||
@@ -10,13 +9,19 @@
|
||||
>
|
||||
<van-row v-for="(item, index) in articleList" :key="index" class="row">
|
||||
<van-col span="4" class="leftCol">
|
||||
<AppUserIcon width="3rem" height="3rem" :src="item.user==null?null:(item.user.icon)"/>
|
||||
<AppUserIcon
|
||||
width="3rem"
|
||||
height="3rem"
|
||||
:src="item.user == null ? null : item.user.icon"
|
||||
/>
|
||||
</van-col>
|
||||
|
||||
<van-col span="14" class="centerTitle">
|
||||
<span class="justtitle">{{item.user==null?"-":(item.user.nick??item.user.username)}}</span>
|
||||
<span class="justtitle">{{
|
||||
item.user == null ? "-" : item.user.nick ?? item.user.username
|
||||
}}</span>
|
||||
<br />
|
||||
<app-createTime :time="item.createTime" />
|
||||
<app-createTime :time="item.creationTime" />
|
||||
</van-col>
|
||||
|
||||
<van-col span="6" class="down">
|
||||
@@ -25,25 +30,44 @@
|
||||
|
||||
<van-col class="rowBody" span="24">{{ item.content }}</van-col>
|
||||
|
||||
<van-col
|
||||
<van-col
|
||||
span="8"
|
||||
v-for="(image, imageIndex) in item.images"
|
||||
:key="imageIndex"
|
||||
class="imageCol"
|
||||
@click="openImage(item.images)"
|
||||
><van-image
|
||||
@click="openImage(item.images, imageIndex)"
|
||||
>
|
||||
<van-image
|
||||
lazy-load
|
||||
fit="cover"
|
||||
width="100%"
|
||||
height="7rem"
|
||||
:src="url + image"
|
||||
:src="url + image + '/true'"
|
||||
radius="5"
|
||||
/>
|
||||
</van-col>
|
||||
<template v-slot:loading>
|
||||
<van-loading type="spinner" size="20" />
|
||||
</template>
|
||||
</van-col>
|
||||
|
||||
<van-col span="24" class="bottomRow">
|
||||
<van-grid direction="horizontal" :column-num="3">
|
||||
<van-grid-item icon="share-o" text="分享" />
|
||||
<van-grid-item icon="comment-o" text="评论" />
|
||||
<van-grid-item icon="good-job-o" text="点赞" />
|
||||
<van-grid-item
|
||||
icon="comment-o"
|
||||
text="评论"
|
||||
@click="openComment(item.id)"
|
||||
/>
|
||||
<!-- <van-grid-item
|
||||
icon="good-job-o"
|
||||
:text="`点赞:${item.agreeNum}`"
|
||||
@click="aggreeHand(item.id)"
|
||||
/> -->
|
||||
<van-grid-item
|
||||
icon="good-job-o"
|
||||
:text="`点赞:10`"
|
||||
@click="aggreeHand(item.id)"
|
||||
/>
|
||||
</van-grid>
|
||||
</van-col>
|
||||
</van-row>
|
||||
@@ -61,20 +85,39 @@
|
||||
<van-image-preview
|
||||
v-model:show="imageShow"
|
||||
:images="imagesPreview"
|
||||
:startPosition="startIndex"
|
||||
@change="onChange"
|
||||
:closeable="true"
|
||||
>
|
||||
<template v-slot:index>第{{ index + 1 }}页</template>
|
||||
</van-image-preview>
|
||||
|
||||
<!-- 评论面板 -->
|
||||
<van-action-sheet v-model:show="commentShow" title="共10条评论">
|
||||
<van-row v-for="i in commentList" :key="i" class="commentContent">
|
||||
<van-col span="4">头像</van-col>
|
||||
<van-col span="16">{{ i.content }}</van-col>
|
||||
<van-col span="4">点赞</van-col>
|
||||
</van-row>
|
||||
|
||||
<van-cell-group inset>
|
||||
<van-field v-model="commentData.content" placeholder="请输入评论" >
|
||||
<template #button>
|
||||
<van-button size="small" type="primary" @click="sendComment()">发布</van-button>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
</van-action-sheet>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive, toRefs } from "vue";
|
||||
import { ImagePreview, Toast } from "vant";
|
||||
import AppCreateTime from "@/components/AppCreateTime.vue";
|
||||
import AppUserIcon from "@/components/AppUserIcon.vue";
|
||||
import articleApi from "@/api/articleApi.ts";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity.ts";
|
||||
import AppUserIcon from "@/components/AppUserIcon.vue";
|
||||
import articleApi from "@/api/articleApi";
|
||||
import agreeApi from "@/api/agreeApi";
|
||||
import commentApi from "@/api/commentApi";
|
||||
const VanImagePreview = ImagePreview.Component;
|
||||
const url = `${import.meta.env.VITE_APP_BASE_API}/file/`;
|
||||
const data = reactive({
|
||||
@@ -86,13 +129,34 @@ const data = reactive({
|
||||
isDeleted: false,
|
||||
},
|
||||
});
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
const articleList = ref<ArticleEntity[]>([]);
|
||||
const commentData = reactive({
|
||||
content: "",
|
||||
articleId:0
|
||||
});
|
||||
const sendComment=()=>{
|
||||
commentData.articleId=openCommentId.value;
|
||||
commentApi.add(commentData).then(()=>{
|
||||
getCommentList(openCommentId.value);
|
||||
commentData.content="";
|
||||
})
|
||||
}
|
||||
|
||||
const { queryParams } = toRefs(data);
|
||||
const {content}=toRefs(commentData);
|
||||
const articleList = ref<any[]>([]);
|
||||
const commentList = ref<any[]>([]);
|
||||
const totol = ref<Number>(0);
|
||||
const imageShow = ref(false);
|
||||
const commentShow = ref<any>(false);
|
||||
const index = ref(0);
|
||||
let imagesPreview = ref<string[]>([]);
|
||||
const openCommentId=ref(0);
|
||||
const openComment = (id: any) => {
|
||||
commentShow.value = true;
|
||||
openCommentId.value=id;
|
||||
getCommentList(id);
|
||||
};
|
||||
|
||||
const onChange = (newIndex: any) => {
|
||||
index.value = newIndex;
|
||||
@@ -102,7 +166,7 @@ const list = ref<Number[]>([]);
|
||||
const loading = ref(false);
|
||||
const finished = ref(false);
|
||||
const refreshing = ref(false);
|
||||
|
||||
const startIndex = ref(0);
|
||||
const show = ref(false);
|
||||
const actions = [{ name: "取消关注" }, { name: "将TA拉黑" }, { name: "举报" }];
|
||||
|
||||
@@ -114,19 +178,17 @@ const onLoad = async () => {
|
||||
// 异步更新数据
|
||||
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
|
||||
articleApi.pageList(queryParams.value).then((response: any) => {
|
||||
if (response.data.data.length == 0) {
|
||||
if (response.data.items.length == 0) {
|
||||
console.log("结束");
|
||||
finished.value = true;
|
||||
} else {
|
||||
console.log("执行");
|
||||
articleList.value.push(...(response.data.data as ArticleEntity[]));
|
||||
articleList.value.push(...response.data.items);
|
||||
totol.value = response.data.totol;
|
||||
queryParams.value.pageNum += 1;
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
|
||||
console.log(loading.value);
|
||||
});
|
||||
};
|
||||
const onRefresh = () => {
|
||||
@@ -138,8 +200,9 @@ const onRefresh = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
onLoad();
|
||||
};
|
||||
const openImage = (imagesUrl: string[]) => {
|
||||
const openImage = (imagesUrl: string[], imageIndex: any) => {
|
||||
imagesPreview.value = imagesUrl.map((i) => url + i);
|
||||
startIndex.value = imageIndex;
|
||||
imageShow.value = true;
|
||||
};
|
||||
onMounted(() => {
|
||||
@@ -147,24 +210,46 @@ onMounted(() => {
|
||||
// getList();
|
||||
});
|
||||
|
||||
const getCommentList = (id: any) => {
|
||||
commentApi.getListByArticleId(id).then((response: any) => {
|
||||
commentList.value = response.data;
|
||||
});
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
articleApi.pageList(queryParams.value).then((response: any) => {
|
||||
articleList.value.push(...(response.data.data as ArticleEntity[]));
|
||||
articleList.value.push(...response.data.data);
|
||||
totol.value = response.data.totol;
|
||||
});
|
||||
};
|
||||
const aggreeHand = (articleId: any) => {
|
||||
agreeApi.operate(articleId).then((response: any) => {
|
||||
//更改显示的值
|
||||
if (response.status) {
|
||||
articleList.value.filter((p) => p.id == articleId)[0].agreeNum += 1;
|
||||
} else {
|
||||
articleList.value.filter((p) => p.id == articleId)[0].agreeNum -= 1;
|
||||
}
|
||||
Toast({
|
||||
message: response.message,
|
||||
position: "bottom",
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.list {
|
||||
background-color: #efefef;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
.row {
|
||||
background-color: white;
|
||||
padding-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.rowBody {
|
||||
text-align: left;
|
||||
background-color: white;
|
||||
@@ -172,22 +257,27 @@ const getList = () => {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding-top: 1rem;
|
||||
|
||||
min-height: 3rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.leftCol {
|
||||
align-content: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.centerTitle {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.imageCol {
|
||||
padding: 0.1rem 0.1rem 0.1rem 0.1rem;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #cbcbcb;
|
||||
}
|
||||
@@ -195,11 +285,17 @@ const getList = () => {
|
||||
.justtitle {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.bottomRow {
|
||||
color: #979797;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.down {
|
||||
text-align: right;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.commentContent {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
</style>
|
||||
@@ -33,14 +33,14 @@
|
||||
<van-row class="btnRow">
|
||||
<van-col span="12">
|
||||
<van-button class="btn">
|
||||
<van-icon name="bag" size="1.8rem" /> 我的购物<van-icon
|
||||
<van-icon name="bag" size="1.8rem" /> <span>我的购物</span><van-icon
|
||||
name="arrow"
|
||||
size="1.2rem" /></van-button
|
||||
></van-col>
|
||||
|
||||
<van-col span="12">
|
||||
<van-button class="btn"
|
||||
><van-icon name="send-gift" size="1.8rem" />我的签到<van-icon
|
||||
><van-icon name="send-gift" size="1.8rem" /> <span>我的签到</span><van-icon
|
||||
name="arrow"
|
||||
size="1.2rem" /></van-button
|
||||
></van-col>
|
||||
@@ -90,10 +90,10 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import AppGrid from "@/components/AppGrid.vue";
|
||||
import { AppGridData } from "@/type/class/AppGridData.ts";
|
||||
import { AppGridData } from "@/type/class/AppGridData";
|
||||
import { ref } from "vue";
|
||||
import { Dialog } from "vant";
|
||||
import useUserStore from "@/store/modules/user";
|
||||
import useUserStore from "@/store/modules/user.js";
|
||||
import { storeToRefs } from 'pinia';
|
||||
import AppUserIcon from "@/components/AppUserIcon.vue";
|
||||
const show = ref<boolean>(false);
|
||||
@@ -177,6 +177,22 @@ const outLog = () => {
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.bodyCol
|
||||
{
|
||||
color: #9B9B9B;
|
||||
}
|
||||
.bodyCol span{
|
||||
color: black;
|
||||
font-size:larger;
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn .van-icon{
|
||||
color: #FF689B;
|
||||
}
|
||||
.btn span{
|
||||
font-size:medium;
|
||||
font-weight:600;
|
||||
}
|
||||
.grid {
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
@@ -198,7 +214,7 @@ const outLog = () => {
|
||||
}
|
||||
.subtitle {
|
||||
line-height: 4rem;
|
||||
color: #cbcbcb;
|
||||
color: #9B9B9B;
|
||||
}
|
||||
.bodyCol {
|
||||
text-align: center;
|
||||
@@ -212,6 +228,7 @@ const outLog = () => {
|
||||
background-color: #ffffff;
|
||||
border: none;
|
||||
color: black;
|
||||
|
||||
}
|
||||
.btnRow {
|
||||
margin-top: 1.5rem;
|
||||
@@ -9,7 +9,12 @@
|
||||
</router-link>
|
||||
</van-col>
|
||||
<van-col span="18"><span>发图文</span></van-col>
|
||||
<van-col span="3" @click="send">发布</van-col>
|
||||
<van-col
|
||||
span="3"
|
||||
@click="send"
|
||||
:style="{ color: isSend ? '#FE70A0' : '#979797' }"
|
||||
>发布</van-col
|
||||
>
|
||||
</van-row>
|
||||
</van-sticky>
|
||||
|
||||
@@ -22,7 +27,7 @@
|
||||
label-width="0"
|
||||
:show-word-limit="true"
|
||||
maxlength="500"
|
||||
placeholder="每一天,都是为了下一天"
|
||||
placeholder="大于5字,每一天,都是为了下一天"
|
||||
/>
|
||||
</van-cell-group>
|
||||
<van-row class="body-row">
|
||||
@@ -31,7 +36,7 @@
|
||||
</van-col>
|
||||
<van-col span="4"></van-col>
|
||||
<van-col span="10"
|
||||
><span>选择更多人看到</span>
|
||||
><span class="right-span">选择更多人看到</span>
|
||||
<van-icon name="arrow" size="1.2rem" />
|
||||
</van-col>
|
||||
</van-row>
|
||||
@@ -39,26 +44,33 @@
|
||||
<van-divider />
|
||||
<van-row>
|
||||
<van-col class="img-col" span="24">
|
||||
<van-uploader :after-read="afterRead" v-model="fileList" multiple />
|
||||
<van-uploader
|
||||
accept="image/*"
|
||||
:after-read="afterRead"
|
||||
v-model="fileList"
|
||||
multiple
|
||||
/>
|
||||
</van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive, toRefs } from "vue";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity.ts";
|
||||
import fileApi from "@/api/fileApi.ts";
|
||||
import articleApi from "@/api/articleApi.ts";
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ref, onMounted, reactive, toRefs, watch } from "vue";
|
||||
import { ArticleEntity } from "@/type/interface/ArticleEntity";
|
||||
import fileApi from "@/api/fileApi";
|
||||
import articleApi from "@/api/articleApi";
|
||||
import { Toast } from "vant";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const form = reactive<ArticleEntity>({
|
||||
const form = reactive<any>({
|
||||
title: "",
|
||||
content: "",
|
||||
images: [],
|
||||
isDeleted: false,
|
||||
});
|
||||
|
||||
const isSend = ref(false);
|
||||
const { images, content } = toRefs(form);
|
||||
const fileList = ref([]);
|
||||
const visible = ref<boolean>(false);
|
||||
@@ -66,42 +78,74 @@ onMounted(() => {
|
||||
visible.value = true;
|
||||
});
|
||||
const afterRead = (file: any) => {
|
||||
|
||||
file.status = "uploading";
|
||||
file.message = "上传中...";
|
||||
var formData = new FormData();
|
||||
//一个文件
|
||||
if(file.length==undefined)
|
||||
{
|
||||
if (file.length == undefined) {
|
||||
formData.append("file", file.file);
|
||||
} else {
|
||||
//多个文件
|
||||
file.forEach((f: any) => {
|
||||
formData.append("file", f.file);
|
||||
f.status = "uploading";
|
||||
f.message = "上传中...";
|
||||
});
|
||||
Toast({
|
||||
message: "全部文件正在上传",
|
||||
position: "bottom",
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
//多个文件
|
||||
file.forEach((f:any) => {
|
||||
formData.append("file", f.file);
|
||||
});
|
||||
}
|
||||
fileApi.upload("image", formData)
|
||||
.then((response: any) => {
|
||||
images.value.push(...response.data);
|
||||
|
||||
fileApi.upload(formData).then((response: any) => {
|
||||
images.value.push(...response.data.map((x:any)=>x.id));
|
||||
|
||||
if (file.length == undefined) {
|
||||
file.status = "done";
|
||||
file.message = "成功";
|
||||
})
|
||||
} else {
|
||||
//多个文件
|
||||
file.forEach((f: any) => {
|
||||
f.status = "done";
|
||||
f.message = "成功";
|
||||
});
|
||||
Toast({
|
||||
message: "全部文件上传成功",
|
||||
position: "bottom",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const send = () => {
|
||||
articleApi.add(form).then((response:any)=>{
|
||||
router.push({ path: '/recommend'});
|
||||
})
|
||||
|
||||
if (form.content.length < 5) {
|
||||
Toast({
|
||||
message: "请输入至少5个字符",
|
||||
position: "bottom",
|
||||
});
|
||||
} else {
|
||||
articleApi.add(form).then((response: any) => {
|
||||
router.push({ path: "/recommend" });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => form.content,
|
||||
(newValue, oldValue) => {
|
||||
if (newValue.length < 5) {
|
||||
isSend.value = false;
|
||||
} else {
|
||||
isSend.value = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style scoped>
|
||||
.head-row {
|
||||
background-color: #f8f8f8;
|
||||
|
||||
padding: 2rem 1rem 1.5rem 1rem;
|
||||
padding: 1.2rem 1rem 0.8rem 1rem;
|
||||
}
|
||||
|
||||
.head-row span {
|
||||
@@ -135,4 +179,7 @@ const send = () => {
|
||||
.img-col {
|
||||
text-align: left;
|
||||
}
|
||||
.right-span {
|
||||
color: #979797;
|
||||
}
|
||||
</style>
|
||||
44
Yi.App.Vue3/src/view/shop/shopDetails.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
这里是商品详情页,当所有规格组全部选择完后,就会匹配sku列表,匹配成功才显示价格,即绑定好的sku
|
||||
|
||||
<div >商品名称:{{spuItem.spuName}}</div>
|
||||
<div v-for="spec in spuItem.specsSpuAllInfo" :key="spec">规格组: {{spec.specsGroupName}}
|
||||
<div v-for="name in spec.specsNames" :key="name">规格值: {{name}}</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<div v-for="sku in spuItem.skus" :key="sku"> 价格:{{sku.price}}<br>Sku:{{sku}}
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
<router-link to="/shopIndex">返回商品首页</router-link>
|
||||
|
||||
<van-action-bar>
|
||||
<van-action-bar-icon icon="chat-o" text="客服" dot />
|
||||
<van-action-bar-icon icon="cart-o" text="购物车" badge="5" />
|
||||
<van-action-bar-icon icon="shop-o" text="店铺" badge="12" />
|
||||
<van-action-bar-button type="warning" text="加入购物车" />
|
||||
<van-action-bar-button type="danger" text="立即购买" />
|
||||
</van-action-bar>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {ref,onMounted} from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import spuApi from "@/api/spuApi";
|
||||
const router = useRouter();
|
||||
|
||||
const spuItem=ref<any>({});
|
||||
|
||||
onMounted(() => {
|
||||
const spuId=router.currentRoute.value.query.spuId;
|
||||
// 打印
|
||||
spuApi.getById(spuId).then((response:any)=>{
|
||||
spuItem.value=response.data
|
||||
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
</script>>
|
||||
79
Yi.App.Vue3/src/view/shop/shopIndex.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template >
|
||||
<div class="back">
|
||||
|
||||
<van-row class="top-div"> <van-col span="3"><van-icon name="circle" size="2rem" /></van-col>
|
||||
<van-col span="18"> <router-link to="/shopSearch"><van-cell-group inset>
|
||||
<van-field label="搜索" placeholder="搜索" />
|
||||
</van-cell-group> </router-link></van-col>
|
||||
<van-col span="3"><van-icon name="circle" size="2rem" /></van-col></van-row>
|
||||
|
||||
<div class="head-div">
|
||||
<van-swipe
|
||||
height="100"
|
||||
class="my-swipe"
|
||||
:autoplay="3000"
|
||||
indicator-color="white"
|
||||
>
|
||||
<van-swipe-item>1</van-swipe-item>
|
||||
<van-swipe-item>2</van-swipe-item>
|
||||
<van-swipe-item>3</van-swipe-item>
|
||||
<van-swipe-item>4</van-swipe-item>
|
||||
</van-swipe>
|
||||
</div>
|
||||
|
||||
<van-row class="body-row">
|
||||
<van-col span="24">
|
||||
<van-grid :column-num="4">
|
||||
<van-grid-item
|
||||
v-for="value in 8"
|
||||
:key="value"
|
||||
icon="photo-o"
|
||||
text="文字"
|
||||
/>
|
||||
</van-grid>
|
||||
</van-col>
|
||||
<van-col span="24"> <AppCard /></van-col>
|
||||
<van-col span="24"> <AppCard /></van-col>
|
||||
<van-col span="24"> <AppCard /></van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import AppCard from "@/components/AppCard.vue";
|
||||
</script>
|
||||
<style>
|
||||
|
||||
.my-swipe .van-swipe-item {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
line-height: 150px;
|
||||
text-align: center;
|
||||
background-color: #39a9ed;
|
||||
}
|
||||
.body-row {
|
||||
padding: 1rem;
|
||||
padding-top: 0.2rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.van-swipe {
|
||||
/* margin-top: 10rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem; */
|
||||
}
|
||||
.head-div {
|
||||
padding: 1rem;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.body-row .van-col {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.top-div
|
||||
{
|
||||
padding: 1rem;
|
||||
padding-bottom: 0;
|
||||
|
||||
}
|
||||
.back{
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
</style>
|
||||
39
Yi.App.Vue3/src/view/shop/shopSearch.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
这里是商品搜索页
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<router-link to="/shopIndex">返回商品首页</router-link>
|
||||
这个是spu:
|
||||
|
||||
<div v-for="item in spuList" :key="item.id">商品名称:{{item.spuName}}
|
||||
<router-link :to="`/shopDetails?spuId=${item.id}`">点击进入该商品详情</router-link>
|
||||
<div v-for="spec in item.specsSpuAllInfo" :key="spec">规格组: {{spec.specsGroupName}}
|
||||
<div v-for="name in spec.specsNames" :key="name">规格值: {{name}}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref,reactive,toRefs} from 'vue'
|
||||
import spuApi from "@/api/spuApi";
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
// dictName: undefined,
|
||||
// dictType: undefined,
|
||||
isDeleted: false,
|
||||
},
|
||||
});
|
||||
const spuList = ref<any[]>([]);
|
||||
const { queryParams } = toRefs(data);
|
||||
spuApi.pageList(queryParams.value).then((response:any)=>{
|
||||
spuList.value=response.data.data;
|
||||
})
|
||||
</script>
|
||||
@@ -13,7 +13,12 @@
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
// "strictPropertyInitialization": false
|
||||
"paths": {
|
||||
"@": ["./src"],
|
||||
// "@/*": ["./src/*"] // 多加个这个,
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/store/modules/user.ts", "src/utils/myaxios.ts"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
@@ -19,7 +19,8 @@ export default defineConfig(({ mode, command }) => {
|
||||
// 设置路径
|
||||
'~': path.resolve(__dirname, './'),
|
||||
// 设置别名
|
||||
'@': path.resolve(__dirname, './src')
|
||||
// '@': path.resolve(__dirname, './src'),
|
||||
"@": path.join(__dirname, "./src"),
|
||||
}
|
||||
},
|
||||
server: {
|
||||
0
Yi.BBS.Vue3/.env
Normal file
2
Yi.BBS.Vue3/.env.development
Normal file
@@ -0,0 +1,2 @@
|
||||
VITE_APP_BASEAPI="/api-dev"
|
||||
VITE_APP_URL="http://localhost:19001/api"
|
||||
1
Yi.BBS.Vue3/.env.production
Normal file
@@ -0,0 +1 @@
|
||||
VITE_APP_BASEAPI="/prod-api"
|
||||
27
Yi.Vue2.x/.gitignore → Yi.BBS.Vue3/.gitignore
vendored
@@ -1,21 +1,26 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
3
Yi.BBS.Vue3/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||
}
|
||||
29
Yi.BBS.Vue3/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# yi-bbs
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
14
Yi.BBS.Vue3/index.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>意社区</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
6840
Yi.BBS.Vue3/package-lock.json
generated
Normal file
34
Yi.BBS.Vue3/package.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "yi-bbs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"axios": "^1.3.4",
|
||||
"echarts": "^5.4.2",
|
||||
"element-plus": "^2.2.32",
|
||||
"highlight": "^0.2.4",
|
||||
"i": "^0.3.7",
|
||||
"marked": "^4.2.12",
|
||||
"mavon-editor": "^3.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.32",
|
||||
"vue": "^3.2.47",
|
||||
"vue-cropper": "1.0.3",
|
||||
"vue-router": "^4.1.6",
|
||||
"yarm": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"sass": "1.52.1",
|
||||
"unplugin-auto-import": "^0.15.0",
|
||||
"unplugin-vue-components": "^0.24.0",
|
||||
"vite": "^4.1.3"
|
||||
}
|
||||
}
|
||||
BIN
Yi.BBS.Vue3/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 21 KiB |
28
Yi.BBS.Vue3/src/App.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-config-provider :locale="locale">
|
||||
<RouterView />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
<script setup>
|
||||
import useConfigStore from "@/stores/config";
|
||||
import { ElConfigProvider } from 'element-plus'
|
||||
import {onMounted } from "vue";
|
||||
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
const locale= zhCn;
|
||||
|
||||
const configStore = useConfigStore();
|
||||
|
||||
//加载全局信息
|
||||
onMounted(async()=>{
|
||||
|
||||
await configStore.getConfig();
|
||||
})
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
17
Yi.BBS.Vue3/src/apis/accessApi.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import request from '@/utils/request'
|
||||
// 触发访问
|
||||
export function access() {
|
||||
return request({
|
||||
url: '/access-log',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 获取本周数据
|
||||
export function getWeek() {
|
||||
return request({
|
||||
url: '/access-log/week',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
79
Yi.BBS.Vue3/src/apis/accountApi.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 登录方法
|
||||
export function login(username, password, code, uuid) {
|
||||
const data = {
|
||||
username,
|
||||
password,
|
||||
code,
|
||||
uuid
|
||||
}
|
||||
return request({
|
||||
url: '/account/login',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 注册方法
|
||||
export function register(userName,password,phone,code,uuid) {
|
||||
const data = {
|
||||
userName,
|
||||
password,
|
||||
phone,
|
||||
code,
|
||||
uuid
|
||||
}
|
||||
return request({
|
||||
url: '/account/register',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
return request({
|
||||
url: '/account',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 退出方法
|
||||
export function logout() {
|
||||
return request({
|
||||
url: '/account/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
export function getCodeImg() {
|
||||
return request({
|
||||
url: '/account/captcha-image',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'get',
|
||||
timeout: 20000
|
||||
})
|
||||
}
|
||||
// 获取短信验证码
|
||||
export function getCodePhone(phone) {
|
||||
return request({
|
||||
url: '/account/captcha-phone',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post',
|
||||
timeout: 20000,
|
||||
data:{phone}
|
||||
})
|
||||
}
|
||||
11
Yi.BBS.Vue3/src/apis/agreeApi.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function operate(discussId){
|
||||
if(discussId==undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return myaxios({
|
||||
url: `/agree/operate/${discussId}`,
|
||||
method: 'post'
|
||||
})
|
||||
};
|
||||
41
Yi.BBS.Vue3/src/apis/articleApi.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function getList(data){
|
||||
return myaxios({
|
||||
url: '/article',
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
};
|
||||
export function get(id){
|
||||
return myaxios({
|
||||
url: `/article/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
};
|
||||
export function add(data){
|
||||
return myaxios({
|
||||
url: `/article`,
|
||||
method: 'post',
|
||||
data:data
|
||||
})
|
||||
};
|
||||
export function update(id,data){
|
||||
return myaxios({
|
||||
url: `/article/${id}`,
|
||||
method: 'put',
|
||||
data:data
|
||||
})
|
||||
};
|
||||
export function del(ids){
|
||||
return myaxios({
|
||||
url: `/article/${ids}`,
|
||||
method: 'delete'
|
||||
})
|
||||
};
|
||||
export function all(discussId)
|
||||
{
|
||||
return myaxios({
|
||||
url: `/article/all/discuss-id/${discussId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
8
Yi.BBS.Vue3/src/apis/bannerApi.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function getList(data){
|
||||
return myaxios({
|
||||
url: '/banner',
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
};
|
||||
22
Yi.BBS.Vue3/src/apis/commentApi.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function getListByDiscussId(discussId,data){
|
||||
return myaxios({
|
||||
url: `/comment/discuss-id/${discussId}`,
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
};
|
||||
export function add(data){
|
||||
return myaxios({
|
||||
url: `/comment`,
|
||||
method: 'post',
|
||||
data:data
|
||||
})
|
||||
};
|
||||
|
||||
export function del(ids){
|
||||
return myaxios({
|
||||
url: `/comment/${ids}`,
|
||||
method: 'delete'
|
||||
})
|
||||
};
|
||||
9
Yi.BBS.Vue3/src/apis/configApi.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import myaxios from '@/utils/request'
|
||||
|
||||
//获取配置
|
||||
export function getAll(){
|
||||
return myaxios({
|
||||
url: '/config',
|
||||
method: 'get'
|
||||
})
|
||||
};
|
||||
51
Yi.BBS.Vue3/src/apis/discussApi.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function getList(data){
|
||||
return myaxios({
|
||||
url: '/discuss',
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
};
|
||||
export function getTopList(data){
|
||||
|
||||
if(data==undefined)
|
||||
{
|
||||
data={isTop:true}
|
||||
}
|
||||
else
|
||||
{
|
||||
data["isTop"]=true;
|
||||
}
|
||||
|
||||
return myaxios({
|
||||
url: '/discuss',
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
};
|
||||
export function get(id){
|
||||
return myaxios({
|
||||
url: `/discuss/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
};
|
||||
export function add(data){
|
||||
return myaxios({
|
||||
url: `/discuss`,
|
||||
method: 'post',
|
||||
data:data
|
||||
})
|
||||
};
|
||||
export function update(id,data){
|
||||
return myaxios({
|
||||
url: `/discuss/${id}`,
|
||||
method: 'put',
|
||||
data:data
|
||||
})
|
||||
};
|
||||
export function del(ids){
|
||||
return myaxios({
|
||||
url: `/discuss/${ids}`,
|
||||
method: 'delete'
|
||||
})
|
||||
};
|
||||
9
Yi.BBS.Vue3/src/apis/fileApi.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function upload(data){
|
||||
return myaxios({
|
||||
url: '/file',
|
||||
method: 'post',
|
||||
data:data,
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
};
|
||||
8
Yi.BBS.Vue3/src/apis/plateApi.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import myaxios from '@/utils/request'
|
||||
export function getList(data){
|
||||
return myaxios({
|
||||
url: '/plate',
|
||||
method: 'get',
|
||||
params:data
|
||||
})
|
||||
};
|
||||
139
Yi.BBS.Vue3/src/apis/userApi.js
Normal file
@@ -0,0 +1,139 @@
|
||||
import myaxios from '@/utils/request'
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
return myaxios({
|
||||
url: '/user',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询用户详细
|
||||
export function getUser(userId) {
|
||||
return myaxios({
|
||||
url: '/user/' + parseStrEmpty(userId),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增用户
|
||||
export function addUser(data) {
|
||||
return myaxios({
|
||||
url: '/user',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户
|
||||
export function updateUser(id, data) {
|
||||
return myaxios({
|
||||
url: `/user/${id}`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
export function delUser(userId) {
|
||||
return myaxios({
|
||||
url: `/user/${userId}`,
|
||||
method: 'delete',
|
||||
})
|
||||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function resetUserPwd(id, password) {
|
||||
const data = {
|
||||
password
|
||||
}
|
||||
|
||||
|
||||
return myaxios({
|
||||
url: `/account/rest-password/${id}`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户状态修改
|
||||
export function changeUserStatus(userId, isDel) {
|
||||
return myaxios({
|
||||
url: `/user/${userId}/${isDel}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询用户个人信息
|
||||
export function getUserProfile() {
|
||||
return myaxios({
|
||||
url: '/account',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户个人信息
|
||||
export function updateUserProfile(data) {
|
||||
return myaxios({
|
||||
url: `/user/profile`,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 只修改用户头像
|
||||
export function updateUserIcon(data) {
|
||||
return myaxios({
|
||||
url: `/account/icon`,
|
||||
method: 'put',
|
||||
data:{icon:data}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
}
|
||||
return myaxios({
|
||||
url: '/account/password',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) {
|
||||
return request({
|
||||
url: '/system/user/profile/avatar',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询授权角色
|
||||
export function getAuthRole(userId) {
|
||||
return request({
|
||||
url: '/system/user/authRole/' + userId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存授权角色
|
||||
export function updateAuthRole(data) {
|
||||
return request({
|
||||
url: '/system/user/authRole',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
// // 查询部门下拉树结构
|
||||
// export function deptTreeSelect() {
|
||||
// return request({
|
||||
// url: '/system/user/deptTree',
|
||||
// method: 'get'
|
||||
// })
|
||||
// }
|
||||
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
0
Yi.BBS.Vue3/src/assets/base.css
Normal file
710
Yi.BBS.Vue3/src/assets/github-markdown.css
Normal file
@@ -0,0 +1,710 @@
|
||||
@font-face {
|
||||
font-family: octicons-link;
|
||||
src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff');
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
line-height: 1.5;
|
||||
color: #24292e;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c {
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c1,
|
||||
.markdown-body .pl-s .pl-v {
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-e,
|
||||
.markdown-body .pl-en {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.markdown-body .pl-smi,
|
||||
.markdown-body .pl-s .pl-s1 {
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ent {
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.markdown-body .pl-k {
|
||||
color: #d73a49;
|
||||
}
|
||||
|
||||
.markdown-body .pl-s,
|
||||
.markdown-body .pl-pds,
|
||||
.markdown-body .pl-s .pl-pse .pl-s1,
|
||||
.markdown-body .pl-sr,
|
||||
.markdown-body .pl-sr .pl-cce,
|
||||
.markdown-body .pl-sr .pl-sre,
|
||||
.markdown-body .pl-sr .pl-sra {
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.markdown-body .pl-v,
|
||||
.markdown-body .pl-smw {
|
||||
color: #e36209;
|
||||
}
|
||||
|
||||
.markdown-body .pl-bu {
|
||||
color: #b31d28;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ii {
|
||||
color: #fafbfc;
|
||||
background-color: #b31d28;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c2 {
|
||||
color: #fafbfc;
|
||||
background-color: #d73a49;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c2::before {
|
||||
content: "^M";
|
||||
}
|
||||
|
||||
.markdown-body .pl-sr .pl-cce {
|
||||
font-weight: bold;
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ml {
|
||||
color: #735c0f;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mh,
|
||||
.markdown-body .pl-mh .pl-en,
|
||||
.markdown-body .pl-ms {
|
||||
font-weight: bold;
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi {
|
||||
font-style: italic;
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mb {
|
||||
font-weight: bold;
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-md {
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi1 {
|
||||
color: #22863a;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mc {
|
||||
color: #e36209;
|
||||
background-color: #ffebda;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi2 {
|
||||
color: #f6f8fa;
|
||||
background-color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mdr {
|
||||
font-weight: bold;
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ba {
|
||||
color: #586069;
|
||||
}
|
||||
|
||||
.markdown-body .pl-sg {
|
||||
color: #959da5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-corl {
|
||||
text-decoration: underline;
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.markdown-body .octicon {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
.markdown-body a:active,
|
||||
.markdown-body a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.markdown-body svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.markdown-body code,
|
||||
.markdown-body kbd,
|
||||
.markdown-body pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.markdown-body [type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
height: 0;
|
||||
margin: 15px 0;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown-body hr::before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body hr::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.markdown-body td,
|
||||
.markdown-body th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown-body ul,
|
||||
.markdown-body ol {
|
||||
padding-left: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ul ol {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.markdown-body ul ul ol,
|
||||
.markdown-body ul ol ol,
|
||||
.markdown-body ol ul ol,
|
||||
.markdown-body ol ol ol {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
|
||||
.markdown-body dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.markdown-body code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown-body .octicon {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.markdown-body .pl-0 {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-1 {
|
||||
padding-left: 4px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-2 {
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-3 {
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-4 {
|
||||
padding-left: 24px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-5 {
|
||||
padding-left: 32px !important;
|
||||
}
|
||||
|
||||
.markdown-body .pl-6 {
|
||||
padding-left: 40px !important;
|
||||
}
|
||||
|
||||
.markdown-body::before {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body::after {
|
||||
display: table;
|
||||
clear: both;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.markdown-body>*:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body>*:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.markdown-body a:not([href]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body .anchor {
|
||||
float: left;
|
||||
padding-right: 4px;
|
||||
margin-left: -20px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.markdown-body .anchor:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.markdown-body p,
|
||||
.markdown-body blockquote,
|
||||
.markdown-body ul,
|
||||
.markdown-body ol,
|
||||
.markdown-body dl,
|
||||
.markdown-body table,
|
||||
.markdown-body pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
height: 0.25em;
|
||||
padding: 0;
|
||||
margin: 24px 0;
|
||||
background-color: #e1e4e8;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
padding: 0 1em;
|
||||
color: #6a737d;
|
||||
border-left: 0.25em solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown-body blockquote>:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown-body blockquote>:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font-size: 11px;
|
||||
line-height: 10px;
|
||||
color: #444d56;
|
||||
vertical-align: middle;
|
||||
background-color: #fafbfc;
|
||||
border: solid 1px #c6cbd1;
|
||||
border-bottom-color: #959da5;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 #959da5;
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
.markdown-body h2,
|
||||
.markdown-body h3,
|
||||
.markdown-body h4,
|
||||
.markdown-body h5,
|
||||
.markdown-body h6 {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.markdown-body h1 .octicon-link,
|
||||
.markdown-body h2 .octicon-link,
|
||||
.markdown-body h3 .octicon-link,
|
||||
.markdown-body h4 .octicon-link,
|
||||
.markdown-body h5 .octicon-link,
|
||||
.markdown-body h6 .octicon-link {
|
||||
color: #1b1f23;
|
||||
vertical-align: middle;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor,
|
||||
.markdown-body h2:hover .anchor,
|
||||
.markdown-body h3:hover .anchor,
|
||||
.markdown-body h4:hover .anchor,
|
||||
.markdown-body h5:hover .anchor,
|
||||
.markdown-body h6:hover .anchor {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor .octicon-link,
|
||||
.markdown-body h2:hover .anchor .octicon-link,
|
||||
.markdown-body h3:hover .anchor .octicon-link,
|
||||
.markdown-body h4:hover .anchor .octicon-link,
|
||||
.markdown-body h5:hover .anchor .octicon-link,
|
||||
.markdown-body h6:hover .anchor .octicon-link {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 2em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
padding-bottom: 0.3em;
|
||||
font-size: 1.5em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
.markdown-body h3 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.markdown-body h4 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body h5 {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.markdown-body h6 {
|
||||
font-size: 0.85em;
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
.markdown-body ul,
|
||||
.markdown-body ol {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
.markdown-body ul ul,
|
||||
.markdown-body ul ol,
|
||||
.markdown-body ol ol,
|
||||
.markdown-body ol ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown-body li>p {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.markdown-body li+li {
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
.markdown-body dl {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body dl dt {
|
||||
padding: 0;
|
||||
margin-top: 16px;
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body dl dd {
|
||||
padding: 0 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.markdown-body table th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body table th,
|
||||
.markdown-body table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown-body table tr {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #c6cbd1;
|
||||
}
|
||||
|
||||
.markdown-body table tr:nth-child(2n) {
|
||||
background-color: #f6f8fa;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
max-width: 100%;
|
||||
box-sizing: content-box;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.markdown-body img[align=right] {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.markdown-body img[align=left] {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.markdown-body code {
|
||||
padding: 0;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(27,31,35,0.05);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown-body code::before,
|
||||
.markdown-body code::after {
|
||||
letter-spacing: -0.2em;
|
||||
content: "\00a0";
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.markdown-body pre>code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
word-break: normal;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body .highlight {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.markdown-body .highlight pre,
|
||||
.markdown-body pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
/* background-color: #f6f8fa; */
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown-body pre code {
|
||||
display: inline;
|
||||
max-width: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
line-height: inherit;
|
||||
word-wrap: normal;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown-body pre code::before,
|
||||
.markdown-body pre code::after {
|
||||
content: normal;
|
||||
}
|
||||
|
||||
.markdown-body .full-commit .btn-outline:not(:disabled):hover {
|
||||
color: #005cc5;
|
||||
border-color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
line-height: 10px;
|
||||
color: #444d56;
|
||||
vertical-align: middle;
|
||||
background-color: #fafbfc;
|
||||
border: solid 1px #d1d5da;
|
||||
border-bottom-color: #c6cbd1;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 -1px 0 #c6cbd1;
|
||||
}
|
||||
|
||||
.markdown-body :checked+.radio-label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-color: #0366d6;
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item+.task-list-item {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.markdown-body .task-list-item input {
|
||||
margin: 0 0.2em 0.25em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
border-bottom-color: #eee;
|
||||
}
|
||||
|
||||
BIN
Yi.BBS.Vue3/src/assets/login_images/QQ.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
Yi.BBS.Vue3/src/assets/login_images/WeChat.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
Yi.BBS.Vue3/src/assets/login_images/login_bg_phone.png
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
Yi.BBS.Vue3/src/assets/login_images/login_two.jpg
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
Yi.BBS.Vue3/src/assets/logo.ico
Normal file
|
After Width: | Height: | Size: 21 KiB |
48
Yi.BBS.Vue3/src/assets/main.css
Normal file
@@ -0,0 +1,48 @@
|
||||
/* @import './base.css'; */
|
||||
/* #app {
|
||||
margin: 0 auto;
|
||||
font-weight: normal;
|
||||
} */
|
||||
|
||||
body
|
||||
{
|
||||
margin: 0 auto;
|
||||
font-weight: normal;
|
||||
}
|
||||
a{
|
||||
text-decoration: none;
|
||||
}
|
||||
/*
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a,
|
||||
.green {
|
||||
text-decoration: none;
|
||||
color: hsla(160, 100%, 37%, 1);
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
a:hover {
|
||||
background-color: hsla(160, 100%, 37%, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
body {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
} */
|
||||
190
Yi.BBS.Vue3/src/assets/styles/index.scss
Normal file
@@ -0,0 +1,190 @@
|
||||
// @import './variables.module.scss';
|
||||
// @import './mixin.scss';
|
||||
// @import './transition.scss';
|
||||
// @import './element-ui.scss';
|
||||
// @import './sidebar.scss';
|
||||
// @import './btn.scss';
|
||||
// @import './ruoyi.scss';
|
||||
|
||||
// body {
|
||||
// height: 100%;
|
||||
// margin: 0;
|
||||
// -moz-osx-font-smoothing: grayscale;
|
||||
// -webkit-font-smoothing: antialiased;
|
||||
// text-rendering: optimizeLegibility;
|
||||
// font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
// }
|
||||
|
||||
// label {
|
||||
// font-weight: 700;
|
||||
// }
|
||||
|
||||
// html {
|
||||
// height: 100%;
|
||||
// box-sizing: border-box;
|
||||
// }
|
||||
|
||||
// #app {
|
||||
// height: 100%;
|
||||
// }
|
||||
|
||||
// *,
|
||||
// *:before,
|
||||
// *:after {
|
||||
// box-sizing: inherit;
|
||||
// }
|
||||
|
||||
// .no-padding {
|
||||
// padding: 0px !important;
|
||||
// }
|
||||
|
||||
// .padding-content {
|
||||
// padding: 4px 0;
|
||||
// }
|
||||
|
||||
// a:focus,
|
||||
// a:active {
|
||||
// outline: none;
|
||||
// }
|
||||
|
||||
// a,
|
||||
// a:focus,
|
||||
// a:hover {
|
||||
// cursor: pointer;
|
||||
// color: inherit;
|
||||
// text-decoration: none;
|
||||
// }
|
||||
|
||||
// div:focus {
|
||||
// outline: none;
|
||||
// }
|
||||
|
||||
// .fr {
|
||||
// float: right;
|
||||
// }
|
||||
|
||||
// .fl {
|
||||
// float: left;
|
||||
// }
|
||||
|
||||
// .pr-5 {
|
||||
// padding-right: 5px;
|
||||
// }
|
||||
|
||||
// .pl-5 {
|
||||
// padding-left: 5px;
|
||||
// }
|
||||
|
||||
// .block {
|
||||
// display: block;
|
||||
// }
|
||||
|
||||
// .pointer {
|
||||
// cursor: pointer;
|
||||
// }
|
||||
|
||||
// .inlineBlock {
|
||||
// display: block;
|
||||
// }
|
||||
|
||||
// .clearfix {
|
||||
// &:after {
|
||||
// visibility: hidden;
|
||||
// display: block;
|
||||
// font-size: 0;
|
||||
// content: " ";
|
||||
// clear: both;
|
||||
// height: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// aside {
|
||||
// background: #eef1f6;
|
||||
// padding: 8px 24px;
|
||||
// margin-bottom: 20px;
|
||||
// border-radius: 2px;
|
||||
// display: block;
|
||||
// line-height: 32px;
|
||||
// font-size: 16px;
|
||||
// font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
// color: #2c3e50;
|
||||
// -webkit-font-smoothing: antialiased;
|
||||
// -moz-osx-font-smoothing: grayscale;
|
||||
|
||||
// a {
|
||||
// color: #337ab7;
|
||||
// cursor: pointer;
|
||||
|
||||
// &:hover {
|
||||
// color: rgb(32, 160, 255);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// .components-container {
|
||||
// margin: 30px 50px;
|
||||
// position: relative;
|
||||
// }
|
||||
|
||||
// .pagination-container {
|
||||
// margin-top: 30px;
|
||||
// }
|
||||
|
||||
.text-center {
|
||||
text-align: center
|
||||
}
|
||||
|
||||
// .sub-navbar {
|
||||
// height: 50px;
|
||||
// line-height: 50px;
|
||||
// position: relative;
|
||||
// width: 100%;
|
||||
// text-align: right;
|
||||
// padding-right: 20px;
|
||||
// transition: 600ms ease position;
|
||||
// background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
|
||||
|
||||
// .subtitle {
|
||||
// font-size: 20px;
|
||||
// color: #fff;
|
||||
// }
|
||||
|
||||
// &.draft {
|
||||
// background: #d0d0d0;
|
||||
// }
|
||||
|
||||
// &.deleted {
|
||||
// background: #d0d0d0;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .link-type,
|
||||
// .link-type:focus {
|
||||
// color: #337ab7;
|
||||
// cursor: pointer;
|
||||
|
||||
// &:hover {
|
||||
// color: rgb(32, 160, 255);
|
||||
// }
|
||||
// }
|
||||
|
||||
// .filter-container {
|
||||
// padding-bottom: 10px;
|
||||
|
||||
// .filter-item {
|
||||
// display: inline-block;
|
||||
// vertical-align: middle;
|
||||
// margin-bottom: 10px;
|
||||
// }
|
||||
// }
|
||||
|
||||
// //refine vue-multiselect plugin
|
||||
// .multiselect {
|
||||
// line-height: 16px;
|
||||
// }
|
||||
|
||||
// .multiselect--active {
|
||||
// z-index: 1000 !important;
|
||||
// }
|
||||
206
Yi.BBS.Vue3/src/assets/styles/login.scss
Normal file
@@ -0,0 +1,206 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
/*公共CSS*/
|
||||
.box {
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: rgb(29, 67, 89);
|
||||
.content {
|
||||
box-shadow: 0px 1px 6px #3B4859;
|
||||
.login-wrapper {
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
.login-form {
|
||||
.form-item {
|
||||
margin: 20px 0;
|
||||
span {
|
||||
display: block;
|
||||
margin: 5px 20px;
|
||||
font-weight: 100;
|
||||
}
|
||||
.input-item {
|
||||
width: 100%;
|
||||
border-radius: 40px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
font-size: 20px;
|
||||
font-weight: 200;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
border-radius: 40px;
|
||||
color: #fff;
|
||||
border: 0;
|
||||
font-weight: 100;
|
||||
margin-top: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.divider {
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
span:nth-child(1) {
|
||||
flex: 1;
|
||||
}
|
||||
span:nth-child(3) {
|
||||
flex: 1;
|
||||
}
|
||||
.line {
|
||||
display: inline-block;
|
||||
max-width: 30%;
|
||||
width: 30%;
|
||||
}
|
||||
.divider-text {
|
||||
vertical-align: middle;
|
||||
margin: 0px 20px;
|
||||
line-height: 0px;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
.other-login-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.other-login-item {
|
||||
border: 1px solid rgb(214, 222, 228);
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*一般大于手机的尺寸CSS*/
|
||||
@media (min-width: 767px) {
|
||||
.box {
|
||||
background-color: #F0F2F5;
|
||||
.content {
|
||||
width: 85vw;
|
||||
height: 90vh;
|
||||
background: url("@/assets/login_images/login_two.jpg") no-repeat;
|
||||
background-size: 90% 100%;
|
||||
position: absolute;
|
||||
right: 15%;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 20px;
|
||||
background-color: #fff;
|
||||
.login-wrapper {
|
||||
width: 25vw;
|
||||
position: absolute;
|
||||
right: 15%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 45px;
|
||||
color: rgb(81, 100, 115);
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.login-form {
|
||||
margin: 10px 0;
|
||||
.form-item {
|
||||
span {
|
||||
color: rgb(81, 100, 115);
|
||||
}
|
||||
.input-item {
|
||||
height: 60px;
|
||||
border: 1px solid rgb(214, 222, 228);
|
||||
}
|
||||
}
|
||||
.login-btn {
|
||||
height: 50px;
|
||||
background-color: rgb(59, 72, 89);
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
.divider {
|
||||
.line {
|
||||
border-bottom: 1px solid rgb(214, 222, 228);
|
||||
}
|
||||
}
|
||||
.other-login-item {
|
||||
border-radius: 20px;
|
||||
img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*手机端CSS*/
|
||||
@media (max-width: 768px) {
|
||||
.box {
|
||||
.content {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: url("@/assets/login_images/login_bg_phone.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
.login-wrapper {
|
||||
width: 70%;
|
||||
height: 60%;
|
||||
padding-top: 15%;
|
||||
h1 {
|
||||
font-size: 30px;
|
||||
color: #fff;
|
||||
}
|
||||
.login-form {
|
||||
.form-item {
|
||||
margin: 10px 0;
|
||||
span {
|
||||
color: rgb(113, 129, 141);
|
||||
}
|
||||
.input-item {
|
||||
height: 30px;
|
||||
border: 1px solid rgb(113, 129, 141);
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.login-btn {
|
||||
height: 40px;
|
||||
background-color: rgb(235, 95, 93);
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.divider {
|
||||
.line {
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
.divider-text {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.other-login-item {
|
||||
border-radius: 15px;
|
||||
img {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
271
Yi.BBS.Vue3/src/assets/styles/ruoyi.scss
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
/** 基础通用 **/
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
|
||||
.el-dialog.scrollbar .el-dialog__body {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
th {
|
||||
word-break: break-word;
|
||||
background-color: #f8f8f9 !important;
|
||||
color: #515a6e;
|
||||
height: 40px !important;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"] + span {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 表单布局 **/
|
||||
.form-header {
|
||||
font-size:15px;
|
||||
color:#6379bb;
|
||||
border-bottom:1px solid #ddd;
|
||||
margin:8px 10px 25px 10px;
|
||||
padding-bottom:5px
|
||||
}
|
||||
|
||||
/** 表格布局 **/
|
||||
.pagination-container {
|
||||
// position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px !important;
|
||||
}
|
||||
|
||||
/* tree border */
|
||||
.tree-border {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e5e6e7;
|
||||
background: #FFFFFF none;
|
||||
border-radius:4px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@media ( max-width : 768px) {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
.pagination-container .el-pagination > .el-pagination__sizes {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table .fixed-width .el-button--small {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-tree-node__content > .el-checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
// .el-card__header {
|
||||
// padding: 14px 15px 7px !important;
|
||||
// min-height: 40px;
|
||||
// }
|
||||
|
||||
// .el-card__body {
|
||||
// padding: 15px 20px 20px 20px !important;
|
||||
// }
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* button color */
|
||||
.el-button--cyan.is-active,
|
||||
.el-button--cyan:active {
|
||||
background: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan:focus,
|
||||
.el-button--cyan:hover {
|
||||
background: #48D1CC;
|
||||
border-color: #48D1CC;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan {
|
||||
background-color: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* text color */
|
||||
.text-navy {
|
||||
color: #1ab394;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #1c84c6;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #23c6c8;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #f8ac59;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ed5565;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* image */
|
||||
.img-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 拖拽列样式 */
|
||||
.sortable-ghost{
|
||||
opacity: .8;
|
||||
color: #fff!important;
|
||||
background: #42b983!important;
|
||||
}
|
||||
|
||||
/* 表格右侧工具栏样式 */
|
||||
.top-right-btn {
|
||||
margin-left: auto;
|
||||
}
|
||||
55
Yi.BBS.Vue3/src/components/AgreeInfo.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<el-button text @click="agree">
|
||||
<el-icon v-if="data.isAgree" color="#409EFF">
|
||||
<CircleCheckFilled />
|
||||
</el-icon>
|
||||
<el-icon v-else color="#1E1E1E">
|
||||
<Pointer />
|
||||
</el-icon> 点赞:{{ data.agreeNum ?? 0 }}</el-button>
|
||||
</template>
|
||||
<script setup>
|
||||
import {onMounted,reactive,watch} from 'vue'
|
||||
import { operate } from '@/apis/agreeApi'
|
||||
|
||||
|
||||
//'isAgree','agreeNum','id'
|
||||
const props = defineProps([ 'data'])
|
||||
|
||||
watch(()=>props,(n)=>{
|
||||
data.id=n.data.id;
|
||||
data.isAgree=n.data.isAgree;
|
||||
data.agreeNum=n.data.agreeNum;
|
||||
},{deep:true})
|
||||
|
||||
|
||||
const data=reactive({
|
||||
id:'',
|
||||
isAgree:false,
|
||||
agreeNum:0
|
||||
})
|
||||
// onMounted(()=>{
|
||||
|
||||
// })
|
||||
//点赞操作
|
||||
const agree = async () => {
|
||||
const response = await operate(data.id)
|
||||
const res = response.data;
|
||||
//提示框,颜色区分
|
||||
if (res.isAgree) {
|
||||
data.isAgree = true;
|
||||
data.agreeNum += 1;
|
||||
ElMessage({
|
||||
message: res.message,
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
else {
|
||||
data.isAgree = false;
|
||||
data.agreeNum-= 1;
|
||||
ElMessage({
|
||||
message: res.message,
|
||||
type: 'warning',
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
43
Yi.BBS.Vue3/src/components/ArticleContentInfo.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="markdown-body" v-html="outputHtml"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { marked } from 'marked';
|
||||
|
||||
import hljs from "highlight.js";
|
||||
//可以设置加载样式切换主题
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
import '@/assets/github-markdown.css'
|
||||
import { ref,watch } from 'vue';
|
||||
|
||||
|
||||
|
||||
const outputHtml=ref("")
|
||||
const props = defineProps(['code'])
|
||||
watch(props,(n,o)=>{
|
||||
marked.setOptions({
|
||||
renderer: new marked.Renderer(),
|
||||
highlight: function(code) {
|
||||
return hljs.highlightAuto(code).value;
|
||||
},
|
||||
pedantic: false,
|
||||
gfm: true,//允许 Git Hub标准的markdown
|
||||
tables: true,//支持表格
|
||||
|
||||
breaks: true,
|
||||
sanitize: false,
|
||||
smartLists: true,
|
||||
smartypants: false,
|
||||
xhtml: false,
|
||||
smartLists: true,
|
||||
}
|
||||
);
|
||||
//需要注意代码块样式
|
||||
outputHtml.value = marked(n.code).replace(/<pre>/g, "<pre class='hljs'>")
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
131
Yi.BBS.Vue3/src/components/AvatarInfo.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template >
|
||||
<div class="avatar">
|
||||
<div class="avatar-left">
|
||||
<el-avatar :size="props.size" :src="iconUrl" />
|
||||
|
||||
<div v-if="props.isSelf">
|
||||
<div class="nick"> {{ userInfo.nick }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!props.isSelf">
|
||||
|
||||
<div class="nick" :class="{ mt_1: props.time != 'undefined' }"> {{ userInfo.nick }}</div>
|
||||
<div class="remarks" v-if="props.time"> {{ props.time }}</div>
|
||||
<div class="remarks">
|
||||
<slot name="bottom" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="info" v-if="!props.isSelf">
|
||||
<el-tag class="ml-2" type="warning">V8</el-tag>
|
||||
<el-tag class="ml-2" type="danger">会员</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<el-button v-if="props.showWatching" type="primary" size="default" icon="Plus">关注</el-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import useUserStore from '@/stores/user'
|
||||
import { reactive, watch, onMounted, computed, ref } from 'vue';
|
||||
//userInfo
|
||||
//{icon,name,role,id},根据判断userInfo是否等于未定义,来觉得是当前登录用户信息,还是其他人信息
|
||||
const props = defineProps(['size', 'showWatching', 'time', 'userInfo', 'isSelf'])
|
||||
const userStore = useUserStore();
|
||||
const userInfo = reactive({
|
||||
icon: "",
|
||||
nick: "",
|
||||
role: [],
|
||||
id: ""
|
||||
});
|
||||
const iconUrl=ref('/src/assets/logo.ico');
|
||||
const iconUrlHandler = () => {
|
||||
if (userInfo.icon == null || userInfo.icon == undefined || userInfo.icon == '') {
|
||||
|
||||
return '/src/assets/logo.ico';
|
||||
}
|
||||
return `${import.meta.env.VITE_APP_BASEAPI}/file/${userInfo.icon}`;
|
||||
}
|
||||
|
||||
watch(userStore, (n) => {
|
||||
if (props.userInfo == undefined) {
|
||||
userInfo.nick = n.name;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
watch(() => props, (n) => {
|
||||
Init();
|
||||
}, { deep: true })
|
||||
|
||||
onMounted(() => {
|
||||
Init();
|
||||
})
|
||||
|
||||
const Init = () => {
|
||||
//使用传入值
|
||||
if (props.userInfo != undefined) {
|
||||
userInfo.icon = props.userInfo.icon;
|
||||
userInfo.nick = props.userInfo.nick;
|
||||
userInfo.role = props.userInfo.role;
|
||||
userInfo.id = props.userInfo.id;
|
||||
iconUrl.value=iconUrlHandler(userInfo.icon)
|
||||
}
|
||||
|
||||
//使用当前登录用户
|
||||
else {
|
||||
|
||||
userInfo.icon = userStore.icon;
|
||||
userInfo.nick = userStore.name;
|
||||
userInfo.role = userStore.role;
|
||||
userInfo.id = userStore.id;
|
||||
iconUrl.value=userInfo.icon;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.mt_1 {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.nick {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-top: 0.6rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.info .el-tag {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
color: white;
|
||||
|
||||
}
|
||||
|
||||
.avatar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.avatar-left {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-avatar {
|
||||
margin-right: 1.2rem;
|
||||
}
|
||||
|
||||
.remarks {
|
||||
padding-top: 0.5rem;
|
||||
color: #8C8C8C;
|
||||
}
|
||||
</style>
|
||||