Compare commits

...

22 Commits
main ... test

Author SHA1 Message Date
黄晖 7159dce862 Merge pull request 'test' (#7) from hh/Glass-ERP-Vue:test into test
Reviewed-on: http://82.157.76.162:3000/Big-Data-Lab/Glass-ERP-Vue/pulls/7
2023-09-20 01:05:12 +08:00
huanghui 37c644df05 第三模块完成 2023-08-17 17:41:57 +08:00
hh 8d93800f57 第三模块开发 2023-08-17 00:56:17 +08:00
huanghui bce709dd64 第二模块完成 2023-08-16 17:43:06 +08:00
hh 69035b3ff7 更新订单处理页面 2023-08-16 01:05:39 +08:00
huanghui 13ff42ea68 第二模块 2023-08-15 17:39:42 +08:00
黄晖 a13dbfbaa9 Merge pull request '更新订单处理页面' (#6) from hh/Glass-ERP-Vue:test into test
Reviewed-on: http://82.157.76.162:3000/Big-Data-Lab/Glass-ERP-Vue/pulls/6
2023-08-15 01:06:49 +08:00
hh 08410361e2 更新订单处理页面 2023-08-15 01:03:05 +08:00
lq 7e562bfc15 Merge pull request '不知道为什么这个版本又可以打包了' (#5) from lq/Glass-ERP-Vue:test into test
Reviewed-on: http://www.gitea.hrbnu.club/Big-Data-Lab/Glass-ERP-Vue/pulls/5
2023-08-14 17:33:18 +08:00
Liuqi 2c0a5f8f9d 不知道为什么这个版本又可以打包了 2023-08-14 17:29:19 +08:00
lq 3f1908f8f5 Merge pull request '重新修改了页脚相关内容' (#4) from lq/Glass-ERP-Vue:test into test
Reviewed-on: http://www.gitea.hrbnu.club/Big-Data-Lab/Glass-ERP-Vue/pulls/4
2023-08-14 17:03:38 +08:00
Liuqi 62b6f6ab4c 重新修改了页脚相关内容 2023-08-14 17:01:51 +08:00
lq 24828eba08 Merge pull request '删除了验证码组件并且复写了一些UI,修改了页脚' (#3) from lq/Glass-ERP-Vue:test into test
Reviewed-on: http://82.157.76.162:3000/Big-Data-Lab/Glass-ERP-Vue/pulls/3
2023-08-14 14:58:12 +08:00
Liuqi 612ffe9bd4 重新修改了登录UI组件的样式 2023-08-14 14:56:51 +08:00
Liuqi da4e43c178 删除了验证码组件并且复写了一些UI 2023-08-14 14:25:45 +08:00
Liuqi eaa4a7fe8b 删除了验证码组件并且复写了一些UI 2023-08-14 14:15:18 +08:00
lq 1ddaf42574 Merge pull request 'test' (#1) from Big-Data-Lab/Glass-ERP-Vue:test into test
Reviewed-on: http://82.157.76.162:3000/lq/Glass-ERP-Vue/pulls/1
2023-08-14 11:20:32 +08:00
黄晖 634d700862 Merge pull request 'test' (#2) from hh/Glass-ERP-Vue:test into test
Reviewed-on: http://82.157.76.162:3000/Big-Data-Lab/Glass-ERP-Vue/pulls/2
2023-08-14 01:03:26 +08:00
黄晖 3ef2bba545 Merge pull request '修改了框架UI' (#1) from lq/Glass-ERP-Vue:test into test
Reviewed-on: http://82.157.76.162:3000/Big-Data-Lab/Glass-ERP-Vue/pulls/1
2023-08-14 00:56:08 +08:00
hh a74e76fea2 更新采购管理的第二模块 2023-08-14 00:55:08 +08:00
hh d760ac5c5c 更新采购管理的第一模块 2023-08-12 20:35:54 +08:00
super 8d100a0325 修改了框架UI 2023-08-12 17:10:33 +08:00
22 changed files with 2549 additions and 512 deletions

4
public/index.html vendored
View File

@ -5,7 +5,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>JeecgBoot 企业级低代码平台</title>
<title>计科院ERP系统</title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<style>
@ -249,7 +249,7 @@
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载 JeecgBoot 低代码平台,请耐心等待
<div class="load_title">正在加载 计科院 ERP系统,请耐心等待
</div>
</div>

BIN
src/assets/background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -1,172 +1,226 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="293px" height="293px" viewBox="0 0 293 293" enable-background="new 0 0 293 293" xml:space="preserve"> <image id="image0" width="293" height="293" x="0" y="0"
href="data:image/png;base64,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
OjAwP26CAAAAAABJRU5ErkJggg==" />
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,400.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1825 3990 c-476 -48 -908 -251 -1236 -579 -477 -479 -678 -1149
-544 -1811 91 -450 339 -861 690 -1144 287 -233 589 -368 965 -433 153 -26
472 -24 630 5 411 75 756 248 1050 529 675 642 814 1674 332 2473 -172 284
-440 545 -732 711 -146 83 -356 165 -520 203 -184 42 -470 63 -635 46z m436
-86 c640 -89 1181 -481 1465 -1059 262 -535 265 -1136 9 -1671 -101 -212 -209
-366 -377 -535 -502 -508 -1270 -692 -1951 -468 -675 221 -1166 782 -1298
1484 -30 157 -37 440 -15 595 63 429 229 773 521 1078 248 258 536 432 875
525 92 26 233 52 315 60 112 10 354 6 456 -9z"/>
<path d="M1811 3869 c-516 -54 -998 -325 -1308 -736 -331 -437 -454 -1001
-336 -1533 81 -368 258 -687 520 -941 164 -158 307 -259 503 -353 592 -284
1280 -239 1838 121 109 70 213 157 323 270 106 109 151 165 222 273 355 548
405 1247 128 1825 -103 215 -194 346 -355 513 -398 411 -969 620 -1535 561z
m458 -44 c610 -89 1146 -488 1404 -1044 325 -703 182 -1531 -358 -2076 -527
-532 -1308 -695 -2000 -418 -536 215 -937 663 -1094 1223 -61 219 -80 525 -46
751 83 559 411 1047 897 1333 194 113 425 195 653 231 117 18 416 18 544 0z"/>
<path d="M2005 3731 c-19 -38 -32 -46 -51 -30 -13 11 -19 9 -35 -11 -23 -31
-24 -68 -2 -92 17 -19 13 -35 -19 -81 -11 -14 -10 -19 2 -27 20 -12 24 -7 45
47 30 77 69 137 101 153 16 9 56 15 91 15 33 0 59 4 56 8 -3 5 -37 7 -77 5
-67 -3 -71 -2 -74 20 -5 30 -19 28 -37 -7z"/>
<path d="M2542 3671 c6 -19 38 -29 68 -20 22 6 21 7 -10 8 -20 1 -42 7 -49 14
-11 10 -13 9 -9 -2z"/>
<path d="M2092 3649 c-9 -14 -19 -18 -33 -14 -20 7 -58 -27 -59 -52 0 -15 46
-17 55 -3 3 6 13 10 22 10 14 0 15 -13 9 -110 -4 -72 -3 -110 4 -110 11 0 13
10 14 100 1 64 1 65 31 68 36 4 77 47 73 75 -2 16 -13 23 -42 29 -22 5 -44 13
-51 18 -7 6 -15 2 -23 -11z m76 -36 c-2 -10 -13 -19 -26 -21 -17 -3 -22 2 -22
17 0 16 6 21 26 21 19 0 25 -5 22 -17z"/>
<path d="M1430 3650 c0 -5 11 -10 25 -10 31 0 32 -16 3 -49 l-23 -26 26 23
c16 14 32 20 42 16 24 -9 21 -19 -10 -39 -16 -10 -40 -29 -55 -43 -26 -24 -26
-25 -9 -41 11 -9 22 -28 25 -43 5 -23 0 -32 -39 -64 -25 -20 -45 -40 -45 -45
0 -15 58 -10 64 6 7 18 37 20 55 3 11 -11 12 -9 6 10 -5 17 1 29 24 52 42 42
78 41 96 -4 8 -19 19 -37 25 -41 17 -11 11 15 -11 45 -26 34 -19 60 16 60 14
0 25 5 25 10 0 15 -41 12 -74 -5 -36 -19 -47 -12 -39 27 5 27 4 30 -11 25 -10
-4 -21 -7 -24 -7 -4 0 0 -5 8 -10 17 -11 6 -36 -23 -54 -23 -15 -33 1 -14 22
21 23 22 39 2 22 -8 -6 -19 -9 -25 -5 -19 12 -10 33 29 64 40 32 55 81 24 81
-9 0 -13 6 -9 15 4 12 -4 15 -39 15 -25 0 -45 -4 -45 -10z"/>
<path d="M2650 3629 c-43 -18 -163 -41 -203 -41 -34 1 -38 -2 -35 -21 3 -25
20 -27 161 -26 62 0 85 -4 114 -21 37 -22 54 -20 34 4 -13 15 -85 36 -125 36
-14 0 -26 4 -26 9 0 13 26 21 70 21 36 0 70 20 70 41 0 12 -28 11 -60 -2z"/>
<path d="M1575 3620 c4 -6 1 -17 -5 -25 -10 -12 -10 -15 2 -15 18 0 38 20 38
37 0 7 -9 13 -21 13 -11 0 -17 -4 -14 -10z"/>
<path d="M1325 3596 c-22 -34 -30 -93 -15 -111 21 -25 28 -8 17 41 -10 44 -9
48 11 62 23 15 29 32 12 32 -5 0 -17 -11 -25 -24z"/>
<path d="M1370 3555 c-7 -14 -10 -28 -7 -32 9 -8 57 17 57 30 0 5 -6 4 -13 -2
-18 -14 -30 -2 -16 16 6 7 7 13 2 13 -5 0 -16 -11 -23 -25z"/>
<path d="M2494 3512 c-13 -9 -74 -116 -74 -131 0 -22 18 -10 46 32 16 23 27
48 26 55 -2 8 4 19 14 26 18 13 6 30 -12 18z"/>
<path d="M2575 3473 c52 -7 59 -11 45 -28 -7 -9 -21 -13 -35 -9 -44 11 -94
-96 -60 -129 23 -23 108 -22 162 3 48 21 63 55 43 98 l-13 27 -12 -35 c-16
-47 -66 -80 -121 -80 -24 0 -46 5 -49 11 -11 17 4 59 21 59 8 0 32 12 52 27
70 52 69 63 -5 62 -32 -1 -44 -4 -28 -6z"/>
<path d="M1311 3365 c1 -53 11 -87 28 -93 11 -4 13 4 7 38 -4 23 -13 54 -21
69 l-14 26 0 -40z"/>
<path d="M826 3278 c4 -24 7 -73 6 -109 -1 -49 2 -68 12 -72 19 -8 42 20 61
73 17 49 41 80 62 80 7 0 13 -9 13 -20 0 -11 -7 -20 -15 -20 -26 0 -29 -30 -6
-60 25 -34 26 -48 6 -74 -11 -15 -17 -16 -28 -7 -12 9 -16 7 -20 -10 -7 -27 1
-47 24 -59 15 -9 21 -5 34 19 8 17 15 37 15 46 0 17 16 20 26 4 3 -6 1 -15 -6
-19 -9 -6 -7 -11 8 -19 50 -27 55 -6 10 44 l-31 36 20 21 c22 21 43 17 43 -8
0 -22 37 -17 55 8 14 21 14 24 -2 35 -23 17 -55 16 -79 -2 -34 -26 -47 -19
-40 23 14 81 13 87 -17 90 -27 3 -78 -35 -88 -67 -11 -32 -29 3 -29 55 0 48
-2 54 -21 54 -19 0 -20 -4 -13 -42z"/>
<path d="M3167 3301 c-2 -11 -24 -29 -47 -41 -42 -21 -72 -22 -114 -5 -18 8
-19 5 -12 -33 6 -38 4 -43 -18 -53 -30 -14 -76 -4 -76 16 0 19 -24 19 -40 0
-17 -21 -1 -79 24 -83 28 -6 62 6 94 33 37 31 43 25 59 -69 12 -72 41 -116 75
-116 33 0 31 29 -6 100 -20 38 -36 81 -36 96 0 28 -2 27 66 8 14 -4 23 0 28
11 8 22 -1 35 -23 35 -10 0 -24 6 -30 14 -13 15 -5 24 47 50 31 16 42 39 23
50 -5 3 -11 -3 -14 -13z"/>
<path d="M1840 3279 c-340 -43 -662 -220 -865 -472 -142 -176 -229 -356 -277
-569 -31 -137 -33 -416 -4 -548 88 -408 348 -745 714 -929 100 -50 112 -54
112 -32 0 14 -21 29 -76 55 -587 279 -879 955 -678 1571 144 440 511 770 969
872 112 24 353 29 476 9 646 -107 1120 -692 1086 -1341 -26 -471 -290 -880
-706 -1094 -61 -31 -101 -58 -101 -67 0 -21 24 -13 135 45 379 197 639 571
696 999 15 110 6 352 -15 452 -48 223 -160 443 -314 619 -147 167 -392 321
-617 386 -165 48 -372 65 -535 44z"/>
<path d="M3466 2904 c-18 -18 -21 -34 -6 -34 6 0 10 5 10 11 0 7 8 18 18 25 9
7 12 14 5 14 -6 0 -19 -7 -27 -16z"/>
<path d="M483 2904 c-8 -4 -6 -11 7 -24 10 -10 21 -37 25 -61 3 -24 13 -66 22
-92 11 -35 12 -52 5 -59 -12 -12 -25 13 -37 65 -9 41 -43 33 -72 -18 -12 -22
-23 -43 -23 -47 0 -16 30 -7 40 12 15 28 27 25 32 -8 6 -41 0 -52 -30 -52
l-27 -1 28 -15 c37 -20 70 -15 82 14 12 26 35 29 35 5 0 -43 21 -93 39 -93 17
0 16 5 -7 75 -13 41 -22 81 -19 90 9 21 34 19 42 -4 9 -30 42 -54 62 -46 12 5
14 9 6 12 -14 5 -17 50 -7 77 3 9 15 16 26 16 15 0 18 -4 12 -17 -4 -10 -8
-31 -8 -48 -1 -23 4 -31 19 -33 11 -1 26 2 34 7 13 8 13 12 0 27 -8 9 -14 33
-14 53 0 33 -2 36 -30 36 -24 0 -34 -7 -50 -37 -11 -21 -26 -38 -32 -38 -21 0
-27 49 -9 69 18 20 20 31 6 31 -6 0 -20 -16 -31 -35 -25 -41 -46 -45 -55 -9
-9 35 7 47 93 73 68 20 93 39 93 70 0 18 -18 12 -67 -23 -52 -36 -110 -59
-125 -50 -5 3 -8 22 -6 43 3 32 0 36 -22 38 -14 1 -30 0 -37 -3z"/>
<path d="M3350 2865 c-25 -13 -53 -24 -62 -25 -10 0 -18 -4 -18 -10 0 -13 0
-14 63 15 l56 24 28 -23 c15 -13 42 -31 60 -40 49 -25 71 -76 33 -76 -24 0
-26 -13 -4 -34 41 -41 67 15 33 72 -24 42 -16 56 27 47 21 -3 34 -2 34 5 0 5
-17 10 -38 10 -55 0 -142 28 -142 45 0 21 -18 18 -70 -10z"/>
<path d="M3520 2871 c0 -6 4 -13 10 -16 6 -3 7 1 4 9 -7 18 -14 21 -14 7z"/>
<path d="M3380 2805 c0 -3 16 -11 35 -19 56 -24 45 -40 -24 -33 -49 4 -61 2
-66 -11 -4 -10 2 -22 17 -33 19 -15 20 -19 9 -33 -16 -19 -57 -21 -67 -4 -4 6
-11 25 -15 42 -6 28 -7 26 -8 -17 -1 -43 2 -49 26 -58 22 -8 32 -6 62 15 23
17 39 22 45 16 16 -16 36 -11 36 8 0 10 -5 23 -11 29 -12 12 -3 37 11 28 13
-8 40 6 40 20 0 7 -16 22 -36 34 -34 20 -54 26 -54 16z"/>
<path d="M1990 2635 c-25 -7 -57 -18 -72 -24 -15 -6 -35 -8 -43 -5 -16 6 -59
-17 -85 -45 -145 -156 -229 -280 -290 -426 -22 -55 -45 -104 -51 -109 -12 -13
-12 -145 2 -222 19 -111 54 -154 211 -260 96 -65 156 -99 205 -114 95 -30 247
-37 392 -16 104 14 120 20 180 58 174 111 270 198 350 316 36 54 71 120 71
136 0 2 -20 28 -45 57 -60 71 -80 123 -66 177 23 84 156 192 238 192 54 0 110
-28 124 -62 16 -39 16 -158 -1 -228 -17 -74 -57 -151 -157 -304 -171 -262
-352 -396 -641 -472 -84 -23 -110 -26 -192 -21 -164 10 -359 81 -524 191 -127
85 -447 420 -470 492 -5 16 -12 20 -26 17 -32 -9 -150 34 -243 87 -48 27 -89
50 -92 50 -19 0 9 -42 103 -156 59 -72 153 -187 209 -255 108 -132 252 -280
318 -328 80 -58 257 -160 331 -191 152 -63 212 -74 399 -74 151 0 181 3 266
26 341 92 599 307 759 631 73 147 84 196 78 352 -6 136 -28 212 -77 259 -38
37 -134 57 -271 59 -146 1 -196 -17 -275 -98 -50 -52 -164 -200 -195 -255 -7
-12 -12 -13 -27 -2 -85 60 -194 82 -283 58 -30 -8 -57 -13 -59 -10 -8 8 50 80
111 140 71 69 157 136 267 208 85 55 81 69 -14 55 -33 -5 -88 -8 -123 -7 -60
1 -67 -1 -125 -43 -107 -77 -297 -280 -297 -317 0 -5 -9 -17 -20 -27 -22 -20
-59 -15 -84 11 -22 21 -13 35 109 179 111 130 169 187 258 254 79 60 73 90
-12 60 -26 -9 -35 -8 -50 5 -10 9 -19 16 -22 15 -2 0 -24 -7 -49 -14z m-238
-552 c26 -23 23 -50 -18 -175 -33 -101 -35 -113 -24 -156 6 -26 20 -62 31 -81
18 -30 18 -36 5 -49 -24 -24 -40 -8 -71 69 -24 59 -30 89 -29 144 1 100 48
265 76 265 6 0 20 -7 30 -17z m777 -149 c37 -47 18 -137 -38 -188 -28 -25 -33
-18 -20 30 6 21 9 66 7 99 -3 33 -3 66 -1 73 7 20 30 14 52 -14z m-639 -120
c0 -49 46 -138 95 -183 27 -25 65 -46 110 -61 62 -21 75 -22 125 -12 110 23
125 13 59 -39 -138 -109 -303 -58 -395 123 -43 85 -45 208 -3 208 5 0 9 -16 9
-36z"/>
<path d="M428 1752 c-93 -20 -115 -37 -37 -27 l57 7 11 -51 c18 -83 16 -89
-26 -97 -21 -4 -45 -10 -53 -15 -25 -14 18 -11 106 7 96 20 132 38 57 29 -58
-7 -51 -14 -68 73 -3 15 -8 35 -11 44 -4 13 4 18 41 23 25 4 48 11 51 16 8 13
-41 10 -128 -9z"/>
<path d="M3470 1735 c0 -6 18 -30 41 -54 22 -24 37 -46 34 -49 -3 -4 -29 -16
-58 -27 -51 -21 -52 -22 -79 -100 -16 -43 -26 -84 -24 -89 2 -6 9 4 16 22 7
17 17 32 23 32 7 -1 50 -14 96 -30 47 -16 87 -27 90 -24 8 8 -14 19 -104 49
-91 31 -88 27 -65 90 9 23 127 70 157 62 51 -14 73 -17 73 -8 0 5 -21 14 -47
20 -36 9 -62 26 -100 64 -29 28 -53 47 -53 42z"/>
<path d="M385 1502 c6 -6 26 -12 45 -14 31 -3 36 -7 53 -53 l19 -50 -33 -27
c-18 -15 -30 -30 -27 -34 11 -10 187 147 181 162 -3 9 -22 14 -57 14 -28 0
-82 3 -121 6 -49 5 -67 3 -60 -4z m200 -22 l30 -1 -35 -30 c-58 -49 -69 -53
-79 -27 -27 72 -27 72 15 65 22 -4 53 -7 69 -7z"/>
<path d="M3362 1370 c4 -13 178 -92 193 -87 5 2 -21 19 -60 37 -120 55 -137
62 -133 50z"/>
<path d="M558 1324 c-91 -45 -123 -79 -42 -43 25 12 47 19 49 17 1 -1 10 -17
19 -35 26 -51 21 -76 -19 -97 -30 -17 -46 -36 -30 -36 12 0 85 51 85 59 0 4
17 8 37 7 30 -1 40 4 51 25 14 23 13 30 -13 87 -15 34 -33 62 -39 61 -6 0 -50
-21 -98 -45z m122 -14 c34 -67 24 -100 -31 -100 -12 0 -27 17 -45 51 -14 28
-24 52 -22 53 5 3 73 35 75 35 2 1 12 -17 23 -39z"/>
<path d="M3305 1275 c-29 -28 -34 -85 -9 -109 23 -23 37 -20 85 19 65 55 75
59 99 35 24 -24 20 -52 -14 -88 -14 -16 -29 -22 -44 -19 -28 5 -39 -9 -13 -18
27 -8 58 10 81 48 25 40 25 69 2 90 -29 26 -57 20 -107 -23 -52 -45 -69 -49
-85 -20 -20 38 12 90 56 90 13 0 24 5 24 10 0 20 -51 10 -75 -15z"/>
<path d="M665 1139 c-49 -33 -91 -62 -93 -64 -7 -7 59 -95 84 -112 24 -15 27
-15 52 4 15 11 28 30 30 42 3 16 8 20 22 16 22 -7 60 26 60 53 0 9 -15 41 -33
69 l-33 53 -89 -61z m113 -4 c26 -41 28 -68 7 -85 -22 -18 -57 0 -83 44 l-21
35 32 20 c18 11 34 21 37 21 3 0 15 -16 28 -35z m-64 -90 c13 -25 13 -33 2
-50 -28 -41 -65 -27 -105 41 l-19 32 36 25 37 25 17 -21 c10 -12 24 -35 32
-52z"/>
<path d="M3191 1093 c-23 -27 -40 -53 -39 -60 3 -13 156 -133 169 -133 19 0 7
16 -31 43 l-40 28 17 31 c10 17 28 37 40 45 20 14 26 13 56 -6 47 -29 69 -26
32 4 -16 14 -42 25 -57 25 -23 0 -28 5 -28 23 0 31 -18 47 -51 47 -20 0 -38
-12 -68 -47z m105 2 c7 -16 -17 -64 -44 -89 -20 -18 -22 -18 -51 4 -17 12 -31
25 -31 30 0 5 18 28 39 50 35 37 42 40 61 30 12 -6 23 -17 26 -25z"/>
<path d="M800 964 c-83 -70 -95 -82 -88 -89 6 -6 160 120 166 136 8 19 -16 5
-78 -47z"/>
<path d="M3070 955 l-54 -55 64 -66 c96 -96 94 -96 151 -33 26 29 46 56 43 59
-3 2 -25 -18 -49 -45 l-43 -50 -31 29 c-17 17 -31 35 -31 41 0 6 16 26 35 45
19 19 35 38 35 44 0 6 -20 -10 -45 -34 l-45 -44 -30 29 -30 29 47 48 c26 26
45 50 42 53 -3 2 -30 -20 -59 -50z"/>
<path d="M841 894 c-90 -97 -93 -120 -3 -31 37 37 70 67 73 67 3 0 -3 -50 -13
-112 -10 -62 -14 -116 -10 -120 11 -11 163 143 155 156 -4 5 -37 -24 -74 -65
-38 -41 -68 -69 -68 -64 -1 6 6 53 14 105 17 111 18 140 6 140 -5 0 -41 -34
-80 -76z"/>
<path d="M2990 872 c0 -6 16 -53 35 -104 19 -51 33 -94 31 -95 -2 -2 -42 19
-89 48 -47 28 -91 49 -97 47 -12 -4 180 -118 198 -118 17 0 16 2 -24 114 -35
97 -54 134 -54 108z"/>
<path d="M1781 853 c-1 -7 -16 -16 -33 -21 l-33 -8 27 -7 26 -7 -19 -72 c-22
-86 -21 -78 -11 -78 11 0 55 175 49 192 -4 10 -6 10 -6 1z"/>
<path d="M2218 819 l-27 -26 24 4 c25 5 33 -12 50 -109 3 -21 10 -38 14 -38 7
0 -24 191 -31 194 -2 1 -15 -10 -30 -25z"/>
<path d="M1880 833 c-42 -15 -54 -78 -21 -107 21 -19 55 -24 84 -12 25 11 23
-24 -3 -52 -27 -28 -63 -28 -83 1 -12 16 -16 18 -16 6 -1 -23 20 -39 52 -39
41 0 63 15 76 51 34 97 -14 179 -89 152z m58 -19 c40 -28 22 -94 -26 -94 -35
0 -52 17 -52 50 0 29 9 45 30 53 23 8 24 8 48 -9z"/>
<path d="M2016 779 c-4 -28 -5 -54 -2 -56 3 -3 15 2 28 11 12 9 28 16 35 16
20 0 53 -38 53 -60 0 -11 -9 -29 -20 -40 -14 -14 -16 -20 -6 -20 18 0 33 19
41 52 5 21 1 33 -20 54 -22 22 -33 25 -61 21 -35 -6 -35 -5 -32 26 3 30 6 32
53 38 l50 6 -56 1 -56 2 -7 -51z"/>
<path d="M1091 689 c-29 -46 -55 -88 -58 -96 -9 -22 16 -14 28 9 7 12 28 47
48 78 l35 55 7 -30 c4 -16 7 -69 8 -117 0 -48 5 -90 11 -93 5 -3 34 31 63 77
71 111 70 108 58 108 -5 0 -31 -34 -58 -75 -26 -41 -51 -75 -55 -75 -4 0 -9
53 -10 117 -2 71 -7 118 -14 120 -6 2 -34 -33 -63 -78z"/>
<path d="M2823 727 c12 -32 113 -167 125 -167 7 0 -5 25 -29 58 -22 31 -51 72
-63 89 -21 32 -43 45 -33 20z"/>
<path d="M2762 692 c2 -4 23 -42 47 -85 23 -43 41 -80 40 -82 -2 -1 -48 19
-102 46 -92 46 -127 58 -127 43 0 -14 104 -194 112 -194 14 0 9 13 -37 94 -25
43 -44 80 -42 82 1 2 49 -19 106 -46 106 -51 121 -57 121 -41 0 15 -104 191
-113 191 -5 0 -7 -3 -5 -8z"/>
<path d="M2011 669 c-1 -20 15 -34 49 -44 22 -6 21 -4 -6 13 -18 11 -34 26
-37 34 -4 9 -6 8 -6 -3z"/>
<path d="M1305 606 c-13 -13 -29 -42 -36 -64 -16 -56 1 -96 52 -123 46 -23 61
-24 99 -4 38 20 60 63 60 119 0 37 -5 48 -31 70 -42 35 -110 36 -144 2z m136
-15 c33 -33 36 -56 14 -108 -20 -47 -41 -62 -88 -63 -68 0 -108 71 -76 133 38
74 99 89 150 38z"/>
<path d="M2580 591 c0 -8 11 -45 26 -84 30 -85 26 -112 -21 -134 -55 -26 -77
-9 -113 84 -17 42 -35 79 -41 81 -14 5 33 -124 58 -158 22 -31 68 -37 111 -15
50 26 55 57 25 145 -27 74 -45 107 -45 81z"/>
<path d="M1515 471 c-15 -53 -30 -102 -32 -108 -3 -7 0 -13 6 -13 6 0 16 21
24 46 7 25 15 45 17 46 25 1 82 -18 95 -32 13 -15 15 -25 7 -54 -6 -21 -7 -38
-1 -41 10 -7 22 37 22 80 0 18 8 35 19 43 10 8 18 25 18 42 0 35 -22 52 -96
73 l-51 15 -28 -97z m152 33 c16 -23 1 -58 -28 -62 -13 -2 -41 1 -62 8 -38 11
-39 12 -32 48 4 20 9 40 11 44 7 11 98 -20 111 -38z"/>
<path d="M1722 443 c-20 -130 -22 -153 -13 -153 8 0 13 22 27 138 4 29 10 50
14 45 4 -4 17 -50 30 -100 12 -51 26 -93 31 -93 5 0 26 33 48 73 22 39 47 81
55 92 15 19 15 19 11 -10 -12 -69 -22 -160 -19 -164 9 -10 15 11 28 105 21
148 1 152 -70 12 -49 -97 -49 -97 -79 22 -22 85 -28 100 -39 100 -10 0 -18
-22 -24 -67z"/>
<path d="M2185 468 c7 -41 25 -170 25 -182 0 -11 132 3 145 15 9 9 -39 6 -102
-7 -26 -5 -27 -1 -43 119 -7 48 -16 87 -21 87 -6 0 -7 -15 -4 -32z"/>
<path d="M2043 473 c-4 -10 -22 -56 -40 -103 -35 -91 -38 -100 -24 -100 4 0
12 15 17 33 9 31 12 32 66 35 57 3 57 3 72 -33 8 -19 19 -35 25 -35 13 0 -81
212 -97 218 -6 2 -15 -5 -19 -15z m61 -114 c-3 -5 -23 -9 -46 -9 -39 0 -40 1
-33 27 3 15 13 43 22 62 l15 36 24 -54 c13 -29 21 -57 18 -62z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -183,7 +183,7 @@
* @param title 要修改的新标题
*/
changeTitle(title) {
let projectTitle = "Jeecg-Boot 企业级低代码平台"
let projectTitle = "计科院ERP系统"
//
if (this.$route.path === indexKey) {
document.title = projectTitle

View File

@ -1,28 +1,32 @@
<template>
<div id="userLayout" :class="['user-layout-wrapper', device]">
<div class="backImg"></div>
<div class="container">
<div class="top">
<div class="header">
<a href="/">
<img src="~@/assets/logo.svg" class="logo" alt="logo">
<span class="title">Jeecg Boot</span>
<img src="~@/assets/logo.svg" class="logo" alt="logo" />
<span class="title">计科院ERP系统</span>
</a>
</div>
<div class="desc">
Jeecg Boot 是中国最具影响力的 企业级 低代码平台
欢迎您登录
</div>
</div>
<route-view></route-view>
<div class="border">
<route-view></route-view>
</div>
<div class="footer">
<div class="links">
<a href="http://doc.jeecg.com" target="_blank">帮助</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">隐私</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE" target="_blank">条款</a>
<a href="https://www.baidu.com" target="_blank">帮助</a>
<a href="https://www.bing.com" target="_blank">隐私</a>
<a href="https://www.baidu.com" target="_blank">条款</a>
</div>
<div class="copyright">
Copyright &copy; 2019 <a href="http://www.jeecg.com" target="_blank">JEECG开源社区</a> 出品
Copyright &copy; <a href="https://www.baidu.com" target="_blank">哈尔滨师范大学人工智能大数据实验室</a> All
right reserved
</div>
</div>
</div>
@ -30,121 +34,146 @@
</template>
<script>
import RouteView from "@/components/layouts/RouteView"
import { mixinDevice } from '@/utils/mixin.js'
import RouteView from '@/components/layouts/RouteView'
import { mixinDevice } from '@/utils/mixin.js'
export default {
name: "UserLayout",
components: { RouteView },
mixins: [mixinDevice],
data () {
return {}
},
mounted () {
document.body.classList.add('userLayout')
},
beforeDestroy () {
document.body.classList.remove('userLayout')
},
export default {
name: 'UserLayout',
components: { RouteView },
mixins: [mixinDevice],
data() {
return {}
},
mounted() {
document.body.classList.add('userLayout')
},
beforeDestroy() {
document.body.classList.remove('userLayout')
}
}
</script>
<style lang="less" scoped>
#userLayout.user-layout-wrapper {
height: 100%;
#userLayout.user-layout-wrapper {
height: 100%;
&.mobile {
.container {
.main {
max-width: 368px;
width: 98%;
}
}
}
.border {
display: block;
width: 50%;
margin: 20px auto;
padding: 25px;
background: #ffffff;
color: black;
border-radius: 15px;
border: 0;
}
.backImg {
width: 100%;
min-height: 100%;
background: #f0f2f5 url(~@/assets/background.jpg) no-repeat 50%;
background-size: 100%;
padding: 110px 0 144px;
position: absolute;
background-size: cover;
left: 0%;
}
&.mobile {
.container {
width: 100%;
min-height: 100%;
background: #f0f2f5 url(~@/assets/background.svg) no-repeat 50%;
background-size: 100%;
padding: 110px 0 144px;
position: relative;
a {
text-decoration: none;
}
.top {
text-align: center;
.header {
height: 44px;
line-height: 44px;
.badge {
position: absolute;
display: inline-block;
line-height: 1;
vertical-align: middle;
margin-left: -12px;
margin-top: -10px;
opacity: 0.8;
}
.logo {
height: 44px;
vertical-align: top;
margin-right: 16px;
border-style: none;
}
.title {
font-size: 33px;
color: rgba(0, 0, 0, .85);
font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-weight: 600;
position: relative;
top: 2px;
}
}
.desc {
font-size: 14px;
color: rgba(0, 0, 0, 0.45);
margin-top: 12px;
margin-bottom: 40px;
}
}
.main {
min-width: 260px;
width: 368px;
margin: 0 auto;
}
.footer {
position: absolute;
width: 100%;
bottom: 0;
padding: 0 16px;
margin: 48px 0 24px;
text-align: center;
.links {
margin-bottom: 8px;
font-size: 14px;
a {
color: rgba(0, 0, 0, 0.45);
transition: all 0.3s;
&:not(:last-child) {
margin-right: 40px;
}
}
}
.copyright {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
}
max-width: 368px;
width: 98%;
}
}
}
</style>
.container {
width: 900px;
background-size: cover;
min-height: 100%;
padding: 110px 0 144px;
position: absolute;
background-size: cover;
right: 0%;
a {
text-decoration: none;
}
.top {
text-align: center;
.header {
height: 44px;
line-height: 44px;
.badge {
position: absolute;
display: inline-block;
line-height: 1;
vertical-align: middle;
margin-left: -12px;
margin-top: -10px;
opacity: 0.8;
}
.logo {
height: 44px;
vertical-align: top;
margin-right: 16px;
border-style: none;
}
.title {
font-size: 33px;
color: white;
font-family: 'Chinese Quote', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol';
font-weight: 600;
position: relative;
top: 2px;
}
}
.desc {
font-size: 30px;
color: white;
margin-top: 15px;
margin-bottom: 40px;
}
}
.main {
min-width: 260px;
width: 368px;
margin: 0 auto;
}
.footer {
position: absolute;
width: 100%;
bottom: 0;
padding: 0 16px;
margin: 48px 0 24px;
text-align: center;
.links {
margin-bottom: 8px;
font-size: 14px;
a {
color: white;
transition: all 0.3s;
&:not(:last-child) {
margin-right: 40px;
}
}
}
.copyright {
color: white;
font-size: 14px;
}
}
}
}
</style>

View File

@ -1,51 +1,37 @@
<template>
<div class="footer">
<div class="links">
<a href="http://www.jeecg.com" target="_blank">JEECG 首页</a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank">
<a-icon type="github"/>
</a>
<a href="https://ant.design/">Ant Design</a>
<a href="https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/">Vue Antd</a>
</div>
<div class="copyright">
Copyright
<a-icon type="copyright"/>
2019 <span>JEECG开源社区 出品</span>
</div>
</div>
<div class="footer"></div>
</template>
<script>
export default {
name: "LayoutFooter"
}
export default {
name: 'LayoutFooter'
}
</script>
<style lang="less" scoped>
.footer {
padding: 0 16px;
margin: 48px 0 24px;
text-align: center;
.footer {
padding: 0 16px;
margin: 48px 0 24px;
text-align: center;
.links {
margin-bottom: 8px;
.links {
margin-bottom: 8px;
a {
color: rgba(0, 0, 0, .45);
a {
color: rgba(0, 0, 0, 0.45);
&:hover {
color: rgba(0, 0, 0, .65);
}
&:hover {
color: rgba(0, 0, 0, 0.65);
}
&:not(:last-child) {
margin-right: 40px;
}
&:not(:last-child) {
margin-right: 40px;
}
}
.copyright {
color: rgba(0, 0, 0, .45);
font-size: 14px;
}
}
</style>
.copyright {
color: rgba(230, 228, 235, 0.45);
font-size: 14px;
}
}
</style>

View File

@ -17,7 +17,7 @@
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="toggle"/>
<span v-if="device === 'desktop'">欢迎进入 Jeecg-Boot 企业级低代码平台</span>
<span v-if="device === 'desktop'">欢迎进入 计科院ERP系统</span>
<span v-else>Jeecg-Boot</span>
<user-menu :theme="theme"/>

View File

@ -21,7 +21,7 @@
props: {
title: {
type: String,
default: 'Jeecg-Boot Pro',
default: '计科院ERP系统',
required: false
},
showTitle: {

View File

@ -0,0 +1,299 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="审批状态">
<j-dict-select-tag placeholder="请选择审批状态" v-model="queryParam.demandStatus"
dictCode="procurement_approval_status" />
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="采购类别">
<j-dict-select-tag placeholder="请选择审批状态" v-model="queryParam.procurementCategory"
dictCode="purchasing_categories" />
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<a-table ref="table" size="middle" :scroll="{ x: true }" bordered rowKey="id" :columns="columns"
:dataSource="dataSource" :pagination="ipagination" :loading="loading"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }" class="j-table-force-nowrap"
@change="handleTableChange">
<template slot="htmlSlot" slot-scope="text, record, index">
<a-button @click="handleButtonClick(record)">详情</a-button>
</template>
<template slot="imgSlot" slot-scope="text,record">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt=""
style="max-width:80px;font-size: 12px;font-style: italic;" />
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button v-else :ghost="true" type="primary" icon="download" size="small" @click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record" v-if="record.isReceiving == 0">
<a-button v-if="record.demandStatus == 3" type="primary" @click="pass(record)">通过</a-button>
<a-button v-else-if="record.demandStatus == 2" type="primary" @click="openNoPassModal(record)">不通过</a-button>
<div v-else>
<a-button type="primary" @click="pass(record)">通过</a-button>
<a-divider type="vertical" />
<a-button type="primary" @click="openNoPassModal(record)">不通过</a-button>
</div>
</span>
<span v-else>
<a>已被接单,不可修改</a>
</span>
</a-table>
<a-modal title="采购内容详情" :visible="see" @ok="handleOk" @cancel="handleOk">
<a-table :columns="contentColumns" :dataSource="content" rowKey="name"></a-table>
</a-modal>
<a-modal title="不通过原因" :visible="noPassSee" @ok="noPassOk" @cancel="noPassCancel">
<a-textarea v-model="tempRecord.auditResults" placeholder="请输入不通过原因" />
</a-modal>
<purchase-request-modal ref="modalForm" @ok="modalFormOk"></purchase-request-modal>
</a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import PurchaseRequestModal from './modules/PurchaseRequestModal.vue'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { postAction } from '@/api/manage'
import { USER_INFO } from "@/store/mutation-types"
import Vue from 'vue'
export default {
name: 'PurchaseRequestList',
mixins: [JeecgListMixin, mixinDevice],
components: {
PurchaseRequestModal
},
data() {
return {
description: '采购表管理页面',
//
see: false,
noPassSee: false,
columns: [
{
title: '审批状态',
align: "center",
dataIndex: 'demandStatus_dictText'
},
{
title: '审核结果',
align: "center",
dataIndex: 'auditResults'
},
{
title: '申请人',
align: "center",
dataIndex: 'createBy_dictText'
},
{
title: '申请日期',
align: "center",
dataIndex: 'createTime'
},
{
title: '需求编号',
align: "center",
dataIndex: 'requirementNumber',
customRender: (text, record, index) => {
//
if (text == null || text == '') {
return ''
}
return 'HL-' + text
}
},
{
title: '申请部门',
align: "center",
dataIndex: 'sysOrgCode'
},
{
title: '采购类别',
align: "center",
dataIndex: 'procurementCategory_dictText'
},
{
title: '采购方向',
align: "center",
dataIndex: 'procurementDirection'
},
{
title: '采购内容',
align: 'center',
dataIndex: 'procurementContent',
scopedSlots: { customRender: 'htmlSlot' }
},
{
title: '采购预算',
align: "center",
dataIndex: 'procurementBudget'
},
{
title: '附件',
align: "center",
dataIndex: 'annex',
scopedSlots: { customRender: 'fileSlot' }
},
{
title: '操作',
dataIndex: 'action',
align: "center",
fixed: "right",
width: 147,
scopedSlots: { customRender: 'action' }
}
],
url: {
list: "/Try/purchaseRequest/list",
edit: "/Try/purchaseRequest/edit",
delete: "/Try/purchaseRequest/delete",
deleteBatch: "/Try/purchaseRequest/deleteBatch",
exportXlsUrl: "/Try/purchaseRequest/exportXls",
importExcelUrl: "Try/purchaseRequest/importExcel",
},
dictOptions: {},
superFieldList: [],
content: [
{
name: '',
number: '',
unit: '',
},
],
contentColumns: [
{
title: '名称',
dataIndex: 'name',
key: 'name',
width: 200
},
{
title: '数量',
dataIndex: 'number',
key: 'number',
width: 80
},
{
title: '单位',
dataIndex: 'unit',
key: 'unit',
width: 80
}
],
//
tempRecord: {},
}
},
created() {
this.getSuperFieldList();
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
methods: {
initDictConfig() {
},
openNoPassModal(record) {
this.noPassSee = true
this.tempRecord = Object.assign({}, record);
this.tempRecord.auditResults = '';
},
noPassOk() {
this.noPassSee = false
//
let record = Object.assign({}, this.tempRecord);
record.demandStatus = 3;
record.approvedBy = Vue.ls.get(USER_INFO).username;
record.auditResults = this.tempRecord.auditResults;
postAction(this.url.edit, record).then(res => {
if (res.success) {
this.$message.success('重新审批成功');
this.loadData();
} else {
this.$message.error(res.message);
}
})
},
noPassCancel() {
this.noPassSee = false
},
handleOk() {
this.see = false
},
handleButtonClick(record) {
this.see = true
if (record.procurementContent == null || record.procurementContent == '') {
this.content = {
name: '',
number: '',
unit: '',
}
} else {
this.content = JSON.parse(record.procurementContent)
}
},
getSuperFieldList() {
let fieldList = [];
fieldList.push({ type: 'sel_user', value: 'createBy', text: '申请人' })
fieldList.push({ type: 'datetime', value: 'createTime', text: '申请日期' })
fieldList.push({ type: 'string', value: 'requirementNumber', text: '需求编号', dictCode: '' })
fieldList.push({ type: 'string', value: 'sysOrgCode', text: '申请部门', dictCode: '' })
fieldList.push({ type: 'int', value: 'demandStatus', text: '需求状态', dictCode: 'procurement_approval_status' })
fieldList.push({ type: 'sel_user', value: 'updateBy', text: '审批人' })
fieldList.push({ type: 'datetime', value: 'updateTime', text: '更新日期' })
fieldList.push({ type: 'int', value: 'procurementCategory', text: '采购类别', dictCode: 'purchasing_categories' })
fieldList.push({ type: 'string', value: 'procurementDirection', text: '采购方向', dictCode: '' })
fieldList.push({ type: 'Text', value: 'procurementContent', text: '采购内容', dictCode: '' })
fieldList.push({ type: 'string', value: 'procurementBudget', text: '采购预算', dictCode: '' })
fieldList.push({ type: 'string', value: 'annex', text: '附件', dictCode: '' })
fieldList.push({ type: 'Text', value: 'auditResults', text: '审核结果', dictCode: '' })
this.superFieldList = fieldList
},
pass(record) {
record.demandStatus = 2;
record.approvedBy = Vue.ls.get(USER_INFO).username;
record.auditResults = '通过';
postAction(this.url.edit, record).then(res => {
if (res.success) {
this.$message.success('重新提交成功');
this.loadData();
} else {
this.$message.error(res.message);
}
})
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

View File

@ -0,0 +1,103 @@
<template>
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<a-form-model ref="form" :model="model" slot="detail">
<a-row>
<a-col :span="24">
<a-form-model-item label="审核结果" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="auditResults">
<a-textarea v-model="model.auditResults" placeholder="请输入审核结果"></a-textarea>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</j-form-container>
</a-spin>
</template>
<script>
import { httpAction, getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
export default {
name: 'PurchaseRequestForm',
components: {
},
props: {
//
disabled: {
type: Boolean,
default: false,
required: false
}
},
data() {
return {
model: {
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
url: {
add: "/Try/purchaseRequest/add",
edit: "/Try/purchaseRequest/edit",
queryById: "/Try/purchaseRequest/queryById"
}
}
},
computed: {
formDisabled() {
return this.disabled
},
},
created() {
//model
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
add() {
this.edit(this.modelDefault);
},
edit(record, id) {
this.model = Object.assign({}, record);
this.visible = true;
console.log(id)
},
submitForm() {
const that = this;
//
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if (!this.model.id) {
httpurl += this.url.add;
method = 'post';
} else {
httpurl += this.url.edit;
method = 'put';
}
httpAction(httpurl, this.model, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok');
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
}
})
},
}
}
</script>

View File

@ -0,0 +1,84 @@
<template>
<a-drawer
:title="title"
:width="width"
placement="right"
:closable="false"
@close="close"
destroyOnClose
:visible="visible">
<purchase-request-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></purchase-request-form>
<div class="drawer-footer">
<a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
<a-button v-if="!disableSubmit" @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import PurchaseRequestForm from './PurchaseRequestForm.vue'
export default {
name: 'PurchaseRequestModal',
components: {
PurchaseRequestForm
},
data () {
return {
title:"操作",
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
});
},
close () {
this.$emit('close');
this.visible = false;
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
handleCancel () {
this.close()
}
}
}
</script>
<style lang="less" scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
.drawer-footer{
position: absolute;
bottom: -8px;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
switchFullscreen
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel"
cancelText="关闭">
<purchase-request-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></purchase-request-form>
</j-modal>
</template>
<script>
import PurchaseRequestForm from './PurchaseRequestForm.vue'
export default {
name: 'PurchaseRequestModal',
components: {
PurchaseRequestForm
},
data () {
return {
title:'',
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
}
}
</script>

View File

@ -0,0 +1,480 @@
<template>
<a-card title="订单处理" :bordered="false">
<template #extra>
<a-button style="margin-left: 10px;" type="primary" @click="Refresh()">刷新</a-button>
</template>
<a-collapse v-model:activeKey="activeKey" accordion v-if="dataShow">
<a-collapse-panel v-for="(item, index) in tableData" :key="index.toString()">
<template slot="header">
<div style="font-size: 18px; font-weight: bold;">
采购订单号:HL-{{ item.requirementNumber }} &nbsp;&nbsp;部门:{{ item.sysOrgCode }}
&nbsp;&nbsp;采购方向:{{ item.procurementDirection }}
<a-button type="primary" style="float: right;margin-left: 10px;"
@click="finish(item)">开始采购</a-button>
<a-button style="float: right;margin-left: 10px;" @click="GenerateQRcode(item)">生成二维码</a-button>
<a-button style="float: right;margin-left: 10px;" @click="generateOrder(item)">生成订单</a-button>
<a-button style="float: right;" @click="receiveNO(item)">取消接单</a-button>
</div>
</template>
<div>
<a-descriptions title="订单详情" bordered>
<a-descriptions-item label="申请人">{{ item.createBy_dictText }}</a-descriptions-item>
<a-descriptions-item label="申请时间">{{ item.createTime }}</a-descriptions-item>
<a-descriptions-item label="申请部门">{{ item.sysOrgCode }}</a-descriptions-item>
<a-descriptions-item label="采购类型">{{ item.procurementCategory_dictText }}</a-descriptions-item>
<a-descriptions-item label="采购预算" :span="3">{{ item.procurementBudget }}</a-descriptions-item>
<a-descriptions-item label="审批人">{{ item.approvedBy_dictText }}</a-descriptions-item>
<a-descriptions-item label="附件" :span="3">
<template>
<span v-if="!item.annex" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button v-else :ghost="true" type="primary" icon="download" size="small"
@click="downloadFile(item.annex)">
下载
</a-button>
</template>
</a-descriptions-item>
<a-descriptions-item label="采购详情(未整理)"
v-if="item.supplierSelection == null || item.supplierSelection == ''">
<div v-for="(item2, index2) in item.procurementContent" :key="index2.toString()">
<a-row>
<a-col :span="2">{{ item2.name }}</a-col>
<a-col :span="2">{{ item2.number }}{{ item2.unit }}</a-col>
</a-row>
</div>
<a-button style="float: right;" type="primary" @click="arrangeOpen(item)">物品和供应商整理</a-button>
</a-descriptions-item>
<a-descriptions-item label="采购详情" v-else>
<a-card style="margin-top: 20px;margin-right: 20px;"
v-for="(item2, index2) in item.supplierSelection" :key="index2.toString()">
<template #title>
{{ item2.supplier }}
</template>
<div v-for="(item3, index3) in item2.goods" :key="index3.toString()">
<a-row :gutter="16" style="margin-top: 5px;">
<a-col :span="8">
<a-input v-model="item3.name" placeholder="物品名称" disabled />
</a-col>
<a-col :span="6">
<a-input v-model="item3.number" placeholder="数量" disabled />
</a-col>
<a-col :span="6">
<a-input v-model="item3.unit" placeholder="单位" disabled />
</a-col>
</a-row>
</div>
</a-card>
<a-button style="margin-top: 10px;float: right;" type="primary"
@click="arrangeOpen(item)">物品和供应商整理</a-button>
</a-descriptions-item>
</a-descriptions>
</div>
</a-collapse-panel>
</a-collapse>
<a-empty v-else>
<template #description>
<span>
订单为空
</span>
</template>
</a-empty>
<a-modal title="采购整理" :visible="arrange" @ok="arrangeOk" @cancel="arrangeCancel">
<div v-if="classifyData.length == 0">
暂无数据
</div>
<div v-else>
<div>
<a-card style="margin-top: 20px;margin-right: 20px;" v-for="(item, index) in classifyData"
:key="index.toString()">
<template #title>
{{ item.supplier }}
<a-button style="float: right;" type="primary" @click="delSupplier(item)">删除公司</a-button>
</template>
<div style="margin-bottom: 20px;">
<a-select v-model:value="selectedFoods" mode="multiple" style="width: 60%"
placeholder="Please select">
<a-select-option v-for="food in classFood" :key="food.name" :value="food.name">
{{ food.name }}
</a-select-option>
</a-select>
<a-button style="float: right;" @click="importFoods(index)">导入</a-button>
<br>
</div>
<div v-for="(item2, index2) in item.goods" :key="index2.toString()">
<a-row :gutter="16" style="margin-top: 5px;">
<a-col :span="8">
<a-input v-model="item2.name" placeholder="物品名称" />
</a-col>
<a-col :span="6">
<a-input v-model="item2.number" placeholder="数量" />
</a-col>
<a-col :span="6">
<a-input v-model="item2.unit" placeholder="单位" />
</a-col>
<a-col :span="2">
<!-- 通过点击按钮触发新增行 -->
<a-icon type="plus-circle" @click="addRow(item2, index)" />
</a-col>
<a-col :span="2">
<!-- 通过点击按钮触发删除行 -->
<a-icon type="minus-circle" @click="removeRow(index, index2)" />
</a-col>
</a-row>
</div>
</a-card>
</div>
</div>
<div>
<a-select mode="default" v-model="selectedSuppliers" style="width: 160px;">
<a-select-option v-for="supplier in classSupplier" :key="supplier.id" :value="supplier.id">
{{ supplier.name }}
</a-select-option>
</a-select>
<a-button type="primary" style="margin-top: 20px;margin-left: 20px;" @click="addSupplier()">添加供应商</a-button>
</div>
</a-modal>
<a-modal title="生成二维码" :visible="QRvis" @ok="QRvis = false" @cancel="QRvis = false">
生成失败
</a-modal>
</a-card>
</template>
<script>
import { getAction, postAction } from '@/api/manage'
import { USER_INFO } from "@/store/mutation-types"
import Vue from 'vue'
export default {
name: 'PurchaseOrderConfirmationList',
data() {
return {
QRvis: false,
url: {
getPurchaseSupplier: "Try/purchaseSupplier/list",
getdata: "/Try/purchaseOrderConfirmation/joinList",
receiveNOurl: "/Try/purchaseOrderConfirmation/cancelReceiving",
editUrl: '/Try/purchaseOrderConfirmation/edit',
finshUrl: '/Try/purchaseOrderConfirmation/finish'
},
activeKey: [],
username: Vue.ls.get(USER_INFO).username,
sysOrgCode: Vue.ls.get(USER_INFO).orgCode,
supplierList: [],
tableData: [],
dataShow: false,
arrange: false,
classifyData: [],
classSupplier: [],
selectedSuppliers: '',
classFood: [],
selectedFoods: [],
poenNmber: '',
QRcode: '',
}
},
computed: {
getPurchaseSupplier: function () {
return `${window._CONFIG['domianURL']}/${this.url.getPurchaseSupplier}`;
},
getdata: function () {
return `${window._CONFIG['domianURL']}/${this.url.getdata}`;
},
receiveNOurl: function () {
return `${window._CONFIG['domianURL']}/${this.url.receiveNOurl}`;
},
editUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.editUrl}`;
},
finshUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.finshUrl}`;
},
},
created() {
this.getSupplierData();
this.getTableData();
},
methods: {
finish(item) {
let newItem = Object.assign({}, item);
newItem.procurementContent = JSON.stringify(newItem.procurementContent);
if (newItem.supplierSelection != null && newItem.supplierSelection != '') {
newItem.supplierSelection = JSON.stringify(newItem.supplierSelection);
} else {
newItem.supplierSelection = '';
}
// procurementLog
newItem.procurementLog = {
'0': newItem.supplierSelection
}
newItem.procurementLog = JSON.stringify(newItem.procurementLog);
//newItemrequirementNumberassociationNumber
newItem.associationNumber = newItem.requirementNumber;
postAction(this.finshUrl, newItem).then(res => {
//200
if (res.code == 200) {
this.$message.success('完成订单成功');
this.getTableData();
} else {
this.$message.error(res.message);
}
})
},
getSupplierData() {
getAction(this.getPurchaseSupplier).then(res => {
//200
if (res.code == 200) {
this.supplierList = res.result.records;
} else {
this.$message.error(res.message);
}
})
},
getTableData() {
this.dataShow = false;
getAction(this.getdata).then(res => {
//200
if (res.code == 200) {
this.tableData = res.result.records;
//
if (this.tableData.length == 0) {
this.dataShow = false;
} else {
this.activeKey = [''];
//
this.tableData.forEach(item => {
item.procurementContent = JSON.parse(item.procurementContent);
});
//supplierSelection
this.tableData.forEach(item => {
if (item.supplierSelection != null && item.supplierSelection != '') {
item.supplierSelection = JSON.parse(item.supplierSelection);
}
});
this.dataShow = true;
}
} else {
this.$message.error(res.message);
}
})
},
receiveNO(item) {
//item
let newItem = Object.assign({}, item);
newItem.procurementContent = JSON.stringify(newItem.procurementContent);
newItem.supplierSelection = JSON.stringify(newItem.supplierSelection);
postAction(this.receiveNOurl, newItem).then(res => {
//200
if (res.code == 200) {
this.$message.success('取消成功');
this.getTableData();
} else {
this.$message.error(res.message);
}
})
},
Refresh() {
this.getSupplierData();
this.getTableData();
},
downloadFile(text) {
if (!text) {
this.$message.warning("未知的文件")
return;
}
if (text.indexOf(",") > 0) {
text = text.substring(0, text.indexOf(","))
}
let url = this.getFileAccessHttpUrl(text)
window.open(url);
},
getFileAccessHttpUrl(avatar, subStr) {
if (!subStr) subStr = 'http'
try {
if (avatar && avatar.startsWith(subStr)) {
return avatar;
} else {
if (avatar && avatar.length > 0 && avatar.indexOf('[') == -1) {
return window._CONFIG['staticDomainURL'] + "/" + avatar;
}
}
} catch (err) {
return;
}
},
generateOrder(item) {
this.$message.success('生成订单成功');
},
//
arrangeOk() {
this.classifyData.forEach((item, index) => {
//itemgoods
item.goods.forEach((item2, index2) => {
//
let flag1 = item2.name == null || item2.name == '' || item2.name == undefined;
let flag2 = item2.number == null || item2.number == '' || item2.number == undefined;
let flag3 = item2.unit == null || item2.unit == '' || item2.unit == undefined;
if (flag1 && flag2 && flag3) {
item.goods.splice(index2, 1);
}
});
});
let data = {
associationNumber: this.poenNmber,
supplierSelection: JSON.stringify(this.classifyData),
}
if (data.supplierSelection == '[]') {
data.supplierSelection = '';
}
postAction(this.editUrl, data).then(res => {
if (res.code == 200) {
this.$message.success('整理成功');
this.arrange = false;
this.getTableData();
//
this.classifyData = [];
this.classSupplier = [];
this.classFood = [];
this.selectedSuppliers = '';
this.selectedFoods = [];
this.poenNmber = '';
} else {
this.$message.error(res.message);
}
})
},
//
arrangeCancel() {
this.arrange = false;
//
this.classifyData = [];
this.classSupplier = [];
this.classFood = [];
this.selectedSuppliers = '';
this.selectedFoods = [];
this.poenNmber = '';
},
//,
arrangeOpen(item) {
//
this.classifyData = [];
this.classSupplier = [];
this.supplierList.forEach(item => {
this.classSupplier.push({
id: item.id,
name: item.name,
});
});
this.classSupplier = Object.assign([], this.classSupplier);
//
this.classFood = Object.assign([], item.procurementContent);
this.poenNmber = item.requirementNumber;
//supplierSelectionnull
if (item.supplierSelection == null || item.supplierSelection == '') {
this.arrange = true;
}
else {
//
let newData = JSON.parse(JSON.stringify(item.supplierSelection))
//classSupplier
newData.forEach(item => {
this.classSupplier.forEach((item2, index2) => {
if (item2.id == item.supplierID) {
this.classSupplier.splice(index2, 1);
}
});
});
//classifyData
this.classifyData = JSON.parse(JSON.stringify(newData))
this.arrange = true;
}
},
//
delSupplier(item) {
//IDclassifyData
this.classifyData.forEach((item2, index2) => {
if (item2.supplierID == item.supplierID) {
this.classifyData.splice(index2, 1);
}
});
//classSupplier
this.classSupplier.push({
id: item.supplierID,
name: item.supplier,
});
},
addSupplier() {
//
if (this.selectedSuppliers == '') {
this.$message.warning('请选择供应商');
return;
}
let selectedID = this.selectedSuppliers;
let selectedSupplier = {};
this.classSupplier.forEach((item, index) => {
if (item.id == selectedID) {
selectedSupplier = Object.assign({}, item);
this.classSupplier.splice(index, 1);
}
});
this.classifyData.push({
supplierID: selectedSupplier.id,
supplier: selectedSupplier.name,
goods: [{
name: '',
number: '',
unit: '',
}
],
});
//
this.selectedSuppliers = '';
},
addRow(item, index) {
this.classifyData[index].goods.push({
name: '',
number: '',
unit: '',
});
},
removeRow(index1, index2) {
this.classifyData[index1].goods.splice(index2, 1);
},
importFoods(index) {
let selectedFoods = this.selectedFoods;
let selectedGoods = [];
this.classFood.forEach(item => {
selectedFoods.forEach(item2 => {
if (item.name == item2) {
selectedGoods.push(item);
}
});
});
//push
selectedGoods.forEach(item => {
this.classifyData[index].goods.push({
name: item.name,
number: item.number,
unit: item.unit,
});
});
this.selectedFoods = [];
},
GenerateQRcode(item) {
this.QRvis = true;
}
},
}
</script>
<style></style>

View File

@ -0,0 +1,184 @@
<template>
<a-card title="采购进程" :bordered="false">
<a-collapse v-model:activeKey="activeKey" accordion>
<a-collapse-panel v-for="(item, index) in dataList" :key="index.toString()">
<template slot="header">
<div style="font-size: 18px; font-weight: bold;">
采购订单号:HL-{{ item.reqirementNumber }}
</div>
</template>
<a-timeline mode="alternate">
<a-timeline-item>
物品整理完毕开始采购
<a-button @click="see(item.procurementLog[0])">查看详情</a-button>
</a-timeline-item>
<a-timeline-item v-for="(item2, index2) in item.procurementLog" :key="index2.toString()" v-if="index2 > 0">
{{ item2 }}
</a-timeline-item>
<a-timeline-item v-if="item.isDone == 1">
采购结束
</a-timeline-item>
</a-timeline>
<div v-if="item.isDone == 0">
<a-button type="primary" style="float: right;margin-bottom: 10px;margin-left: 10px;"
@click="addLog(item)">添加日志</a-button>
<a-button type="primary" style="float: right;margin-bottom: 10px;" @click="endLog(item)">采购结束</a-button>
</div>
<div v-if="item.isDone == 1&&item.qualityIsPass == 0">
<a-button type="primary" style="float: right;margin-bottom: 10px;" @click="end(item)">完成质检</a-button>
</div>
<div v-if="item.isDone == 1&&item.qualityIsPass == 1">
<a-button type="primary" style="float: center;margin-bottom: 10px;" disabled>已完成质检</a-button>
</div>
</a-collapse-panel>
</a-collapse>
<a-modal v-model="seeModal" title="整理详情" width="800px" @ok="seeModal = false" @cancel="seeModal = false">
<a-card style="margin-top: 20px;margin-right: 20px;" v-for="(item2, index2) in supplierSelection"
:key="index2.toString()">
<template #title>
{{ item2.supplier }}
</template>
<div v-for="(item3, index3) in item2.goods" :key="index3.toString()">
<a-row :gutter="16" style="margin-top: 5px;">
<a-col :span="8">
<a-input v-model="item3.name" placeholder="物品名称" disabled />
</a-col>
<a-col :span="6">
<a-input v-model="item3.number" placeholder="数量" disabled />
</a-col>
<a-col :span="6">
<a-input v-model="item3.unit" placeholder="单位" disabled />
</a-col>
</a-row>
</div>
</a-card>
</a-modal>
<a-modal v-model="logModal" title="新增日志" width="800px" @ok="addLogText()" @cancel="logModal = false">
<a-textarea v-model="log" :autosize="{ minRows: 4, maxRows: 8 }" />
</a-modal>
</a-card>
</template>
<script>
import { getAction, postAction } from '@/api/manage'
export default {
data() {
return {
dataList: [],
url: {
list: "/Try/procurementProgress/list",
edit: "/Try/procurementProgress/edit",
},
activeKey: [''],
supplierSelection: [],
seeModal: false,
logModal: false,
log: '',
addData: {}
}
},
created() {
this.getData()
},
computed: {
list: function () {
return `${window._CONFIG['domianURL']}/${this.url.list}`;
},
edit: function () {
return `${window._CONFIG['domianURL']}/${this.url.edit}`;
},
},
methods: {
getData() {
getAction(this.list, {}).then(res => {
let dataList = res.result.records
dataList.forEach(element => {
let Log = JSON.parse(element.procurementLog)
element.procurementLog = Log
})
this.dataList = Object.assign({}, dataList)
console.log(this.dataList)
})
},
see(item) {
this.supplierSelection = item
this.seeModal = true
},
addLog(item) {
this.logModal = true
this.log = ''
this.addData = Object.assign({}, item)
},
addLogText() {
//procurementLog.index
let index = 0
for (const key in this.addData.procurementLog)
if (this.addData.procurementLog.hasOwnProperty(key))
index = key
index = parseInt(index) + 1
//addData
const date = new Date()
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
let currentTime = `${year}-${month}-${day} ${hour}:${minute}:${second}`
this.log = currentTime + ' ' + this.log
this.addData.procurementLog[index] = this.log
//dataJSON
this.addData.procurementLog = JSON.stringify(this.addData.procurementLog)
postAction(this.edit, this.addData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.getData()
} else {
this.$message.error(res.message)
}
})
this.getData()
this.logModal = false
},
endLog(item) {
//isDone1
this.addData = Object.assign({}, item)
this.addData.isDone = 1
//dataJSON
this.addData.procurementLog = JSON.stringify(this.addData.procurementLog)
postAction(this.edit, this.addData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.getData()
} else {
this.$message.error(res.message)
}
})
},
end(item) {
this.addData = Object.assign({}, item)
this.addData.qualityIsPass = 1
//dataJSON
this.addData.procurementLog = JSON.stringify(this.addData.procurementLog)
postAction(this.edit, this.addData).then(res => {
if (res.success) {
this.$message.success(res.message)
this.getData()
} else {
this.$message.error(res.message)
}
})
}
}
}
</script>

View File

@ -0,0 +1,137 @@
<template>
<a-card title="订单接收" :bordered="false">
<template #extra>
<a-button type="primary" @click="getdata()">刷新</a-button>
</template>
<a-collapse v-model:activeKey="activeKey" accordion v-if="dataShow">
<a-collapse-panel v-for="(item, index) in dataList" :key="index.toString()">
<template slot="header">
<div style="font-size: 18px; font-weight: bold;">
采购订单号:HL-{{ item.requirementNumber }} &nbsp;&nbsp;部门:{{ item.sysOrgCode }}
&nbsp;&nbsp;采购方向:{{ item.procurementDirection }}
<a-button style="float: right;" @click="receiveData(item)">接收</a-button>
</div>
</template>
<div>
<a-descriptions title="订单详情" bordered>
<a-descriptions-item label="申请人">{{ item.createBy_dictText }}</a-descriptions-item>
<a-descriptions-item label="申请时间">{{ item.createTime }}</a-descriptions-item>
<a-descriptions-item label="申请部门">{{ item.sysOrgCode }}</a-descriptions-item>
<a-descriptions-item label="采购类型">{{ item.procurementCategory_dictText }}</a-descriptions-item>
<a-descriptions-item label="采购预算" :span="3">{{ item.procurementBudget }}</a-descriptions-item>
<a-descriptions-item label="审批人" :span="3">{{ item.approvedBy_dictText }}</a-descriptions-item>
<a-descriptions-item label="采购详情">
<div v-for="(item2, index2) in item.procurementContent" :key="index2.toString()">
<a-row>
<a-col :span="2">{{ item2.name }}</a-col>
<a-col :span="2">{{ item2.number }}{{ item2.unit }}</a-col>
</a-row>
</div>
</a-descriptions-item>
</a-descriptions>
</div>
</a-collapse-panel>
</a-collapse>
<a-empty v-else>
<template #description>
<span>
订单为空
</span>
</template>
</a-empty>
<a-modal title="填写接收备注" :visible="receive" @ok="receiveOk" @cancel="receiveCancel">
<a-textarea v-model="auditResults" placeholder="请输入接收备注" />
</a-modal>
</a-card>
</template>
<script>
import { getAction, postAction } from '@/api/manage'
import { USER_INFO } from "@/store/mutation-types"
import Vue from 'vue'
export default {
name: 'PurchaseOrderConfirmationList',
data() {
return {
description: '采购订单确认管理页面',
dataList: [],
activeKey: [],
url: {
list: "/Try/purchaseRequest/waitForReceiveList",
acceptReceiving: "Try/purchaseOrderConfirmation/acceptReceiving",
},
receive: false,
tempNO: '',
auditResults: '',
username: Vue.ls.get(USER_INFO).username,
sysOrgCode: Vue.ls.get(USER_INFO).orgCode,
dataShow: false,
}
},
computed: {
list: function () {
return `${window._CONFIG['domianURL']}/${this.url.list}`;
},
acceptReceiving: function () {
return `${window._CONFIG['domianURL']}/${this.url.acceptReceiving}`;
}
},
created() {
this.getdata();
},
methods: {
receiveData(item) {
this.tempNO = item.requirementNumber;
this.receive = true;
},
receiveOk() {
let data = {
associationNumber: this.tempNO,
receiver: this.username,
notes: this.auditResults,
receivingTime: new Date(),
}
postAction(this.acceptReceiving, data).then(res => {
//200
if (res.code == 200) {
this.$message.success('接收成功');
this.getdata();
} else {
this.$message.error(res.message);
}
})
this.receive = false;
},
receiveCancel() {
this.receive = false;
},
getdata() {
this.dataShow = false;
getAction(this.list, {}).then(res => {
//200
if (res.code == 200) {
this.dataList = res.result.records;
if (this.dataList.length == 0) {
this.dataShow = false;
} else {
this.activeKey = [''];
//procurementContentjson
this.dataList.forEach(item => {
item.procurementContent = JSON.parse(item.procurementContent);
});
this.dataShow = true;
console.log(this.dataList);
}
} else {
this.$message.error(res.message);
}
})
}
}
}
</script>

View File

@ -0,0 +1,290 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="审批状态">
<j-dict-select-tag placeholder="请选择审批状态" v-model="queryParam.demandStatus"
dictCode="procurement_approval_status" />
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="采购类别">
<j-dict-select-tag placeholder="请选择审批状态" v-model="queryParam.procurementCategory"
dictCode="purchasing_categories" />
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<!-- 高级查询区域 -->
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete" />删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">
{{ selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table ref="table" size="middle" :scroll="{ x: true }" bordered rowKey="id" :columns="columns"
:dataSource="dataSource" :pagination="ipagination" :loading="loading"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }" class="j-table-force-nowrap"
@change="handleTableChange">
<template slot="htmlSlot" slot-scope="text, record, index">
<a-button @click="handleButtonClick(record)">详情</a-button>
</template>
<template slot="imgSlot" slot-scope="text,record">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt=""
style="max-width:80px;font-size: 12px;font-style: italic;" />
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button v-else :ghost="true" type="primary" icon="download" size="small" @click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record" v-if="record.demandStatus == 3">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
<a-divider type="vertical" v-if="record.demandStatus == 3" />
<a-button type="primary" v-if="record.demandStatus == 3" @click="reSubmit(record)">重新提交</a-button>
</span>
<span v-else-if="record.demandStatus == 2">
<a>已通过申请不可修改</a>
</span>
<span v-else-if="record.demandStatus == 1">
<a>审核中不可修改</a>
</span>
</a-table>
</div>
<a-modal title="采购内容详情" :visible="see" @ok="handleOk" @cancel="handleOk">
<a-table :columns="contentColumns" :dataSource="content" rowKey="name"></a-table>
</a-modal>
<purchase-request-modal ref="modalForm" @ok="modalFormOk"></purchase-request-modal>
</a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import PurchaseRequestModal from './modules/PurchaseRequestModal.vue'
import { postAction } from '@/api/manage'
export default {
name: 'PurchaseRequestList',
mixins: [JeecgListMixin, mixinDevice],
components: {
PurchaseRequestModal
},
data() {
return {
description: '采购表管理页面',
//
columns: [
{
title: '审批状态',
align: "center",
dataIndex: 'demandStatus_dictText'
},
{
title: '审批人',
align: "center",
dataIndex: 'approvedBy_dictText'
},
{
title: '审核结果',
align: "center",
dataIndex: 'auditResults'
},
{
title: '需求编号',
align: "center",
dataIndex: 'requirementNumber',
customRender: (text, record, index) => {
//
if (text == null || text == '') {
return ''
}
return 'HL-' + text
}
},
{
title: '申请日期',
align: "center",
dataIndex: 'createTime'
},
{
title: '采购类别',
align: "center",
dataIndex: 'procurementCategory_dictText',
customRender: (text, record, index) => {
//
if (text == null || text == '') {
return ''
}
return 'HL-' + text
}
},
{
title: '采购方向',
align: "center",
dataIndex: 'procurementDirection',
},
{
title: '采购内容',
align: 'center',
dataIndex: 'procurementContent',
scopedSlots: { customRender: 'htmlSlot' }
},
{
title: '采购预算',
align: "center",
dataIndex: 'procurementBudget'
},
{
title: '附件',
align: "center",
dataIndex: 'annex',
scopedSlots: { customRender: 'fileSlot' }
},
{
title: '操作',
dataIndex: 'action',
align: "center",
fixed: "right",
width: 147,
scopedSlots: { customRender: 'action' }
}
],
see: false,
url: {
list: "/Try/purchaseRequest/selfList",
delete: "/Try/purchaseRequest/delete",
deleteBatch: "/Try/purchaseRequest/deleteBatch",
exportXlsUrl: "/Try/purchaseRequest/exportXls",
importExcelUrl: "Try/purchaseRequest/importExcel",
reSubmit: "/Try/purchaseRequest/reSubmit",
},
content: [
{
name: '',
number: '',
},
],
contentColumns: [
{
title: '名称',
dataIndex: 'name',
key: 'name',
width: 200
},
{
title: '数量',
dataIndex: 'number',
key: 'number',
width: 80
},
{
title: '单位',
dataIndex: 'unit',
key: 'unit',
width: 80
}
],
dictOptions: {},
superFieldList: [],
}
},
created() {
this.getSuperFieldList();
},
computed: {
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
importExcelUrl: function () {
return `${window._CONFIG['domianURL']}/${this.url.reSubmit}`;
},
},
methods: {
initDictConfig() {
},
handleOk() {
this.see = false
},
handleButtonClick(record) {
this.see = true
if (record.procurementContent == null || record.procurementContent == '') {
this.content = {
name: '',
number: '',
}
} else {
this.content = JSON.parse(record.procurementContent)
}
},
getSuperFieldList() {
let fieldList = [];
fieldList.push({ type: 'sel_user', value: 'createBy', text: '申请人' })
fieldList.push({ type: 'datetime', value: 'createTime', text: '申请日期' })
fieldList.push({ type: 'string', value: 'requirementNumber', text: '需求编号', dictCode: '' })
fieldList.push({ type: 'string', value: 'sysOrgCode', text: '申请部门', dictCode: '' })
fieldList.push({ type: 'int', value: 'demandStatus', text: '审批状态', dictCode: 'procurement_approval_status' })
fieldList.push({ type: 'sel_user', value: 'updateBy', text: '审批人' })
fieldList.push({ type: 'datetime', value: 'updateTime', text: '更新日期' })
fieldList.push({ type: 'int', value: 'procurementCategory', text: '采购类别', dictCode: 'purchasing_categories' })
fieldList.push({ type: 'string', value: 'procurementDirection', text: '采购方向', dictCode: '' })
fieldList.push({ type: 'Text', value: 'procurementContent', text: '采购内容', dictCode: '' })
fieldList.push({ type: 'string', value: 'procurementBudget', text: '采购预算', dictCode: '' })
fieldList.push({ type: 'string', value: 'annex', text: '附件', dictCode: '' })
fieldList.push({ type: 'Text', value: 'auditResults', text: '审核结果', dictCode: '' })
this.superFieldList = fieldList
},
reSubmit(record) {
postAction(this.url.reSubmit, record).then(res => {
if (res.success) {
this.$message.success('重新提交成功');
this.loadData();
} else {
this.$message.error(res.message);
}
})
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

View File

@ -0,0 +1,202 @@
<template>
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
<a-row>
<a-col :span="24">
<a-form-model-item label="采购类别" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="procurementCategory">
<j-dict-select-tag type="list" v-model="model.procurementCategory" dictCode="purchasing_categories"
placeholder="请选择采购类别" />
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="采购方向" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="procurementDirection">
<a-input v-model="model.procurementDirection" placeholder="请输入采购方向"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="采购内容" :labelCol="labelCol" :wrapperCol="wrapperCol">
<!-- 循环渲染 content 数组中的每个对象 -->
<div v-for="(item, index) in content" :key="index">
<a-row :gutter="16">
<a-col :span="8">
<a-input v-model="item.name" placeholder="物品名称" />
</a-col>
<a-col :span="6">
<a-input v-model="item.number" placeholder="数量" />
</a-col>
<a-col :span="6">
<a-input v-model="item.unit" placeholder="单位" />
</a-col>
<a-col :span="2">
<!-- 通过点击按钮触发新增行 -->
<a-icon type="plus-circle" @click="addRow(index)" />
</a-col>
<a-col :span="2">
<!-- 通过点击按钮触发删除行 -->
<a-icon type="minus-circle" @click="removeRow(index)" />
</a-col>
</a-row>
</div>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="采购预算" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="procurementBudget">
<a-input v-model="model.procurementBudget" placeholder="请输入采购预算"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="附件" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="annex">
<j-upload v-model="model.annex"></j-upload>
</a-form-model-item>
</a-col>
<a-col :span="24" style="display:none">
<a-form-model-item label="申请人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="annex">
<j-upload v-model="model.createBy"></j-upload>
</a-form-model-item>
</a-col>
<a-col :span="24" style="display:none">
<a-form-model-item label="申请部门" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="annex">
<j-upload v-model="model.sysOrgCode"></j-upload>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</j-form-container>
</a-spin>
</template>
<script>
import { httpAction, getAction } from '@/api/manage'
import { USER_INFO } from "@/store/mutation-types"
import Vue from 'vue'
export default {
name: 'PurchaseRequestForm',
components: {
},
props: {
//
disabled: {
type: Boolean,
default: false,
required: false
}
},
data() {
return {
model: {
createBy: Vue.ls.get(USER_INFO).username,
sysOrgCode: Vue.ls.get(USER_INFO).orgCode,
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
validatorRules: {
procurementCategory: [
{ required: true, message: '请输入采购类别!' },
],
procurementDirection: [
{ required: true, message: '请输入采购方向!' },
],
procurementContent: [
{ required: true, message: '请输入采购内容!' },
],
procurementBudget: [
{ required: true, message: '请输入采购预算!' },
],
},
url: {
add: "/Try/purchaseRequest/add",
edit: "/Try/purchaseRequest/edit",
queryById: "/Try/purchaseRequest/queryById",
},
content: [
{
name: '',
number: '',
unit: '',
},
]
}
},
computed: {
formDisabled() {
return this.disabled
},
},
created() {
//model
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
add() {
this.edit(this.modelDefault);
},
addRow(index) {
this.content.splice(index + 1, 0, {
name: '',
number: '',
unit: '',
});
},
//
removeRow(index) {
//
if (this.content.length === 1) {
return;
}
this.content.splice(index, 1);
},
edit(record) {
this.model = Object.assign({}, record);
//procurementContent
console.log(this.model.procurementContent)
if (this.model.procurementContent != undefined && this.model.procurementContent != null) {
this.content = JSON.parse(this.model.procurementContent);
}
console.log(this.content)
this.visible = true;
},
submitForm() {
//contentJSONmodel.procurementContent
this.model.procurementContent = JSON.stringify(this.content);
//
const that = this;
//
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if (!this.model.id) {
httpurl += this.url.add;
method = 'post';
} else {
httpurl += this.url.edit;
method = 'put';
}
httpAction(httpurl, this.model, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok');
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
}
})
},
}
}
</script>

View File

@ -0,0 +1,84 @@
<template>
<a-drawer
:title="title"
:width="width"
placement="right"
:closable="false"
@close="close"
destroyOnClose
:visible="visible">
<purchase-request-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></purchase-request-form>
<div class="drawer-footer">
<a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
<a-button v-if="!disableSubmit" @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import PurchaseRequestForm from './PurchaseRequestForm.vue'
export default {
name: 'PurchaseRequestModal',
components: {
PurchaseRequestForm
},
data () {
return {
title:"操作",
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
});
},
close () {
this.$emit('close');
this.visible = false;
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
handleCancel () {
this.close()
}
}
}
</script>
<style lang="less" scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
.drawer-footer{
position: absolute;
bottom: -8px;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
switchFullscreen
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel"
cancelText="关闭">
<purchase-request-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></purchase-request-form>
</j-modal>
</template>
<script>
import PurchaseRequestForm from './PurchaseRequestForm.vue'
export default {
name: 'PurchaseRequestModal',
components: {
PurchaseRequestForm
},
data () {
return {
title:'',
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
}
}
</script>

View File

@ -1,160 +1,147 @@
<template>
<div>
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item required prop="username">
<a-input v-model="model.username" size="large" placeholder="请输入帐户名 / admin">
<a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-model-item>
<a-form-model-item required prop="password">
<a-input v-model="model.password" size="large" type="password" autocomplete="false" placeholder="请输入密码 / 123456">
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-model-item>
<a-row :gutter="0">
<a-col :span="16">
<a-form-model-item required prop="inputCode">
<a-input v-model="model.inputCode" size="large" type="text" placeholder="请输入验证码">
<a-icon slot="prefix" type="smile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-model-item>
</a-col>
<a-col :span="8" style="text-align: right">
<img v-if="requestCodeSuccess" style="margin-top: 2px;" :src="randCodeImage" @click="handleChangeCheckCode"/>
<img v-else style="margin-top: 2px;" src="../../assets/checkcode.png" @click="handleChangeCheckCode"/>
</a-col>
</a-row>
</a-form-model>
</div>
<div>
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item required prop="username">
<a-input v-model="model.username" size="large" placeholder="请输入帐户名 / admin">
<a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }" />
</a-input>
</a-form-model-item>
<a-form-model-item required prop="password">
<a-input
v-model="model.password"
size="large"
type="password"
autocomplete="false"
placeholder="请输入密码 / 123456"
>
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }" />
</a-input>
</a-form-model-item>
</a-form-model>
</div>
</template>
<script>
import { getAction } from '@/api/manage'
import Vue from 'vue'
import { mapActions } from 'vuex'
import { getAction } from '@/api/manage'
import Vue from 'vue'
import { mapActions } from 'vuex'
export default {
name: 'LoginAccount',
data(){
return {
requestCodeSuccess: false,
randCodeImage: '',
currdatetime: '',
loginType: 0,
model:{
username: 'admin',
password: '123456',
inputCode: ''
},
validatorRules:{
username: [
{ required: true, message: '请输入用户名!' },
{ validator: this.handleUsernameOrEmail }
],
password: [{
required: true, message: '请输入密码!', validator: 'click'
}],
inputCode: [{
required: true, message: '请输入验证码!'
}]
}
}
},
created() {
this.handleChangeCheckCode();
},
methods:{
...mapActions(['Login']),
/**刷新验证码*/
handleChangeCheckCode(){
this.currdatetime = new Date().getTime();
this.model.inputCode = ''
getAction(`/sys/randomImage/${this.currdatetime}`).then(res=>{
if(res.success){
this.randCodeImage = res.result
this.requestCodeSuccess=true
}else{
this.$message.error(res.message)
this.requestCodeSuccess=false
export default {
name: 'LoginAccount',
data() {
return {
requestCodeSuccess: false,
randCodeImage: '',
currdatetime: '',
loginType: 0,
model: {
username: 'admin',
password: '123456'
},
validatorRules: {
username: [{ required: true, message: '请输入用户名!' }, { validator: this.handleUsernameOrEmail }],
password: [
{
required: true,
message: '请输入密码!',
validator: 'click'
}
]
}
}
},
created() {
this.handleChangeCheckCode()
},
methods: {
...mapActions(['Login']),
/**刷新验证码*/
handleChangeCheckCode() {
this.currdatetime = new Date().getTime()
getAction(`/sys/randomImage/${this.currdatetime}`)
.then(res => {
if (res.success) {
this.randCodeImage = res.result
this.requestCodeSuccess = true
} else {
this.$message.error(res.message)
this.requestCodeSuccess = false
}
}).catch(()=>{
this.requestCodeSuccess=false
})
},
//
handleUsernameOrEmail (rule, value, callback) {
const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;
if (regex.test(value)) {
this.loginType = 0
} else {
this.loginType = 1
}
callback()
},
/**
* 验证字段
* @param arr
* @param callback
*/
validateFields(arr, callback){
let promiseArray = []
for(let item of arr){
let p = new Promise((resolve, reject) => {
this.$refs['form'].validateField(item, (err)=>{
if(!err){
resolve();
}else{
reject(err);
}
})
});
promiseArray.push(p)
}
Promise.all(promiseArray).then(()=>{
.catch(() => {
this.requestCodeSuccess = false
})
},
//
handleUsernameOrEmail(rule, value, callback) {
const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/
if (regex.test(value)) {
this.loginType = 0
} else {
this.loginType = 1
}
callback()
},
/**
* 验证字段
* @param arr
* @param callback
*/
validateFields(arr, callback) {
let promiseArray = []
for (let item of arr) {
let p = new Promise((resolve, reject) => {
this.$refs['form'].validateField(item, err => {
if (!err) {
resolve()
} else {
reject(err)
}
})
})
promiseArray.push(p)
}
Promise.all(promiseArray)
.then(() => {
callback()
}).catch(err=>{
})
.catch(err => {
callback(err)
})
},
acceptUsername(username){
this.model['username'] = username
},
//
handleLogin(rememberMe){
this.validateFields([ 'username', 'password', 'inputCode' ], (err)=>{
if(!err){
let loginParams = {
username: this.model.username,
password: this.model.password,
captcha: this.model.inputCode,
checkKey: this.currdatetime,
remember_me: rememberMe,
}
console.log("登录参数", loginParams)
this.Login(loginParams).then((res) => {
},
acceptUsername(username) {
this.model['username'] = username
},
//
handleLogin(rememberMe) {
this.validateFields(['username', 'password'], err => {
if (!err) {
let loginParams = {
username: this.model.username,
password: this.model.password,
checkKey: this.currdatetime,
remember_me: rememberMe
}
console.log('登录参数', loginParams)
this.Login(loginParams)
.then(res => {
this.$emit('success', res.result)
}).catch((err) => {
})
.catch(err => {
//update-begin-author: taoyan date:20220425 for: #41
if(err && err.code===412){
this.handleChangeCheckCode();
if (err && err.code === 412) {
this.handleChangeCheckCode()
}
//update-end-author: taoyan date:20220425 for: #41
this.$emit('fail', err)
});
}else{
this.$emit('validateFail')
}
})
}
})
} else {
this.$emit('validateFail')
}
})
}
}
}
</script>
<style scoped>
</style>
<style scoped></style>

View File

@ -4,7 +4,7 @@
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在登录 JeecgBoot 低代码平台请耐心等待</div>
<div class="load_title">正在登录 计科院ERP系统请耐心等待</div>
</div>
</div>
</template>

View File

@ -2,13 +2,18 @@
<div>
<div class="user-login-other">
<span>其他登录方式</span>
<a @click="onThirdLogin('github')" title="github"><a-icon class="item-icon" type="github"></a-icon></a>
<a @click="onThirdLogin('wechat_enterprise')" title="企业微信"> <icon-font class="item-icon" type="icon-qiyeweixin3" /></a>
<a @click="onThirdLogin('dingtalk')" title="钉钉"><a-icon class="item-icon" type="dingding"></a-icon></a>
<a @click="onThirdLogin('wechat_open')" title="微信"><a-icon class="item-icon" type="wechat"></a-icon></a>
<a href="https://www.baidu.com" title="github"><a-icon class="item-icon" type="github"></a-icon></a>
<a href="https://www.baidu.com" title="企业微信"> <icon-font class="item-icon" type="icon-qiyeweixin3"/></a>
<a href="https://www.baidu.com" title="钉钉"><a-icon class="item-icon" type="dingding"></a-icon></a>
<a href="https://www.bing.com" title="微信"><a-icon class="item-icon" type="wechat"></a-icon></a>
</div>
<!-- 第三方登录绑定账号密码输入弹框 -->
<a-modal title="请输入密码" :visible="thirdPasswordShow" @ok="thirdLoginCheckPassword" @cancel="thirdLoginNoPassword">
<a-modal
title="请输入密码"
:visible="thirdPasswordShow"
@ok="thirdLoginCheckPassword"
@cancel="thirdLoginNoPassword"
>
<a-input-password placeholder="请输入密码" v-model="thirdLoginPassword" />
</a-modal>
@ -16,7 +21,7 @@
<a-modal :footer="null" :closable="false" :visible="thirdConfirmShow" :class="'ant-modal-confirm'">
<div class="ant-modal-confirm-body-wrapper">
<div class="ant-modal-confirm-body">
<a-icon type="question-circle" style="color:#faad14"/>
<a-icon type="question-circle" style="color:#faad14" />
<span class="ant-modal-confirm-title">提示</span>
<div class="ant-modal-confirm-content">
已有同名账号存在,请确认是否绑定该账号
@ -41,34 +46,27 @@
<span>绑定手机号</span>
</a-form-model-item>
<a-form-model-item>
<a-input
size="large"
type="text"
placeholder="手机号"
v-model="thirdPhone">
<a-icon slot="prefix" type="mobile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
<a-input size="large" type="text" placeholder="手机号" v-model="thirdPhone">
<a-icon slot="prefix" type="mobile" :style="{ color: 'rgba(0,0,0,.25)' }" />
</a-input>
</a-form-model-item>
<a-row :gutter="16">
<a-col class="gutter-row" :span="16">
<a-form-model-item>
<a-input
size="large"
type="text"
placeholder="请输入验证码"
v-model="thirdCaptcha">
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
<a-input size="large" type="text" placeholder="请输入验证码" v-model="thirdCaptcha">
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }" />
</a-input>
</a-form-model-item>
</a-col>
<a-col class="gutter-row" :span="8">
<a-button
class="getCaptcha"
tabindex="-1"
:disabled="thirdState.smsSendBtn"
@click.stop.prevent="getThirdCaptcha"
v-text="!thirdState.smsSendBtn && '获取验证码' || (thirdState.time+' s')"></a-button>
class="getCaptcha"
tabindex="-1"
:disabled="thirdState.smsSendBtn"
@click.stop.prevent="getThirdCaptcha"
v-text="(!thirdState.smsSendBtn && '获取验证码') || thirdState.time + ' s'"
></a-button>
</a-col>
</a-row>
</div>
@ -78,17 +76,17 @@
<script>
import { JeecgThirdLoginMixin } from '@views/user/third/JeecgThirdLoginMixin'
import { Icon } from 'ant-design-vue';
import { Icon } from 'ant-design-vue'
const IconFont = Icon.createFromIconfontCN({
// scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
scriptUrl: '/cdn/font-icon/font_2316098_umqusozousr.js',
});
// scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
scriptUrl: '/cdn/font-icon/font_2316098_umqusozousr.js'
})
export default {
name: 'thirdLogin',
mixins: [JeecgThirdLoginMixin],
components: {
IconFont,
IconFont
}
}
</script>
@ -99,20 +97,20 @@ export default {
margin-top: 24px;
line-height: 22px;
.item-icon {
font-size: 24px;
color: rgba(0, 0, 0, .2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color .3s;
.item-icon {
font-size: 24px;
color: rgba(0, 0, 0, 0.2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color 0.3s;
& :hover {
color: #1890ff;
& :hover {
color: #1890ff;
}
}
.register {
float: right;
}
}
}
.register {
float: right;
}
}
</style>
</style>