Compare commits

...

46 Commits

Author SHA1 Message Date
shy
4aa4eb691f opt some 2025-04-25 18:23:19 +08:00
shy
29d61783d2 opt some 2025-03-22 12:57:45 +08:00
shy
f55256dee2 opt some 2025-03-15 20:46:34 +08:00
shy
2a2f9e7b3e add some 2025-03-15 20:27:02 +08:00
shy
f1ab27b595 add some 2025-03-15 13:16:15 +08:00
shy
1308ebda7b opt some 2025-03-10 19:01:49 +08:00
shy
5376decbf0 add some 2025-03-10 18:38:44 +08:00
shy
a7aa40ad65 opt some 2025-03-08 08:39:38 +08:00
shy
4f5556781d opt some 2025-03-08 08:39:25 +08:00
shy
9941c35ce4 opt some 2025-03-06 09:06:33 +08:00
shy
2d2774c7f2 opt some 2025-03-05 23:33:36 +08:00
shy
832fe1fc15 opt some 2025-03-03 19:50:14 +08:00
shy
088a2089c1 add some 2025-03-03 07:52:51 +08:00
shy
19ca86b7dc opt some 2025-02-28 21:29:40 +08:00
shy
d18f4fe4b6 opt some 2025-02-28 14:28:02 +08:00
shy
9eb70a7223 add some 2025-02-27 18:30:14 +08:00
shy
a80316a9b8 add some 2025-02-27 18:28:38 +08:00
shy
792498076a add some 2025-02-27 16:27:31 +08:00
shy
c7075c93d5 add some 2025-02-27 14:37:53 +08:00
shy
35d0d9ac31 opt some 2025-02-26 22:19:27 +08:00
shy
0985dc1d7f add some 2025-02-25 09:59:33 +08:00
shy
af29281507 add some 2025-02-23 08:03:35 +08:00
shy
b9a4ee596e add some 2025-02-16 08:36:11 +08:00
shy
ce240c802e add some 2025-02-14 16:15:48 +08:00
shy
54107ef29b add some 2025-02-12 23:51:34 +08:00
shy
ad73f75781 add some 2025-02-12 23:49:40 +08:00
shy
bb06a72e52 add some 2025-01-05 16:00:55 +08:00
shy
ff0f5a6db8 add some 2025-01-05 15:59:34 +08:00
shy
013cff1b88 add some 2025-01-05 15:57:02 +08:00
shy
ecf60e6bfa opt some 2024-12-29 19:33:09 +08:00
shy
99a0808a2e opt some 2024-12-17 15:37:51 +08:00
shy
a53bebe50f add some 2024-12-17 15:37:19 +08:00
shy
7ce1c751aa add some 2024-12-16 15:17:20 +08:00
shy
15a1b424b0 opt some 2024-12-15 09:28:32 +08:00
shy
a05a435956 add some 2024-12-14 18:35:32 +08:00
shy
165c5356ca add some 2024-12-08 22:27:28 +08:00
shy
3d470a09c8 add some 2024-12-05 09:54:30 +08:00
shy
5eeef3daf9 add some 2024-12-04 20:15:32 +08:00
root
6cdb89dcfd add some 2024-11-27 14:56:39 +08:00
shy
30ffc4c02b add some 2024-11-25 10:05:10 +08:00
root
3095cdc9e0 add some 2024-11-12 13:12:31 +08:00
root
02edfda6a3 add some 2024-11-12 13:11:46 +08:00
root
7a3d9cc335 add some 2024-10-25 17:49:19 +08:00
root
bbdf9f7c0f add some 2024-10-20 22:55:53 +08:00
root
7605248c1e add some 2024-10-20 18:46:27 +08:00
root
ca2e986e05 add some 2024-10-17 23:46:30 +08:00
64 changed files with 2153 additions and 581 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 shylinux
Copyright (c) 2017-2025 shylinux
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -18,4 +18,4 @@ 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.
SOFTWARE.

View File

@ -1,11 +1,11 @@
# Contexts
Contexts 通过模块化、集群化、自动化的方式,只用一个 20M 大小的程序文件,就可以在各种设备上,一键启动完整的云计算服务与云研发环境。
# ContextOS
ContextOS 通过集群化、模块化、自动化的方式,只用一个 20M 大小的程序文件,就可以在各种设备上,一键启动完整的云计算服务与云研发环境。
## 源码安装
### 克隆编译
## 安装系统
### 下载编译
```sh
git clone https://shylinux.com/x/contexts
cd contexts; source etc/miss.sh
git clone https://shylinux.com/x/ContextOS
cd ContextOS; source etc/miss.sh
```
### 启动服务
@ -13,7 +13,5 @@ cd contexts; source etc/miss.sh
ish_miss_serve
```
### 访问网页
```sh
open http://localhost:9020
```
### 管理后台
打开管理后台 [http://localhost:9020](http://localhost:9020)

52
go.mod
View File

@ -1,12 +1,50 @@
module shylinux.com/x/operation
go 1.13
go 1.21
require (
shylinux.com/x/community v0.0.12
shylinux.com/x/enterprise v0.0.8
shylinux.com/x/ice v1.5.48
shylinux.com/x/icebergs v1.9.48
shylinux.com/x/mysql-story v0.6.22
shylinux.com/x/toolkits v1.0.15
2025-dev.shylinux.com/x/20250211-service v0.0.6
2025-dev.shylinux.com/x/20250215-cluster v0.0.7
shylinux.com/x/community v0.0.28
shylinux.com/x/enterprise v0.0.17
shylinux.com/x/golang-story v0.0.32 // indirect
shylinux.com/x/mysql-story v0.6.32
)
require (
shylinux.com/x/ice v1.5.74
shylinux.com/x/icebergs v1.9.76
shylinux.com/x/toolkits v1.0.19
)
require (
shylinux.com/x/go-git/v5 v5.6.7 // indirect
shylinux.com/x/go-qrcode v0.0.3 // indirect
shylinux.com/x/websocket v0.0.4 // indirect
)
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emersion/go-imap v1.2.1 // indirect
github.com/emersion/go-message v0.15.0 // indirect
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/glebarez/sqlite v1.11.0 // indirect
github.com/go-sql-driver/mysql v1.9.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/wechatpay-apiv3/wechatpay-go v0.2.20 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.22.0 // indirect
gorm.io/driver/mysql v1.5.7 // indirect
gorm.io/gorm v1.25.12 // indirect
modernc.org/libc v1.22.5 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.23.1 // indirect
)

256
go.sum
View File

@ -1,13 +1,21 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/bgould/http v0.0.0-20190627042742-d268792bdee7/go.mod h1:BTqvVegvwifopl4KTEDth6Zezs9eR+lCWhvGKvkxJHE=
2025-dev.shylinux.com/x/20250211-service v0.0.6 h1:FOQ6Z+eHsY+3qfIoKHjblbIs6BUyHPq1xGK1wvFdfXo=
2025-dev.shylinux.com/x/20250211-service v0.0.6/go.mod h1:iHH7uHRP7WasG19pNjujlXwZFjJqzX3dS0/T1imfsj0=
2025-dev.shylinux.com/x/20250215-cluster v0.0.6/go.mod h1:4sbNfB+nBVmIpRSzVlY+uiEQv44JdPfwwBpwWzbQktw=
2025-dev.shylinux.com/x/20250215-cluster v0.0.7 h1:GhQImaF6RbliJ6467gdeB4AVzCNyz5LwmA9AeCphEvo=
2025-dev.shylinux.com/x/20250215-cluster v0.0.7/go.mod h1:rhNacwQogLrmiNkmoptqpKY9ieRXAhVHenHwZRcdBB8=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dhowden/itl v0.0.0-20170329215456-9fbe21093131/go.mod h1:eVWQJVQ67aMvYhpkDwaH2Goy2vo6v8JCMfGXfQ9sPtw=
github.com/dhowden/plist v0.0.0-20141002110153-5db6e0d9931a/go.mod h1:sLjdR6uwx3L6/Py8F+QgAfeiuY87xuYGwCDqRFrvCzw=
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8/go.mod h1:apkPC/CR3s48O2D7Y++n1XWEpgPNNCjXYga3PPbJe2E=
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjTA=
github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY=
github.com/emersion/go-message v0.15.0 h1:urgKGqt2JAc9NFJcgncQcohHdiYb803YTH9OQwHBHIY=
@ -16,231 +24,187 @@ github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1X
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 h1:IbFBtwoTQyw0fIM5xv1HF+Y+3ZijDR839WMulgxCcUY=
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
github.com/glerchundi/subcommands v0.0.0-20181212083838-923a6ccb11f8/go.mod h1:r0g3O7Y5lrWXgDfcFBRgnAKzjmPgTzwoMC2ieB345FY=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo=
github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/hajimehoshi/go-jisx0208 v1.0.0/go.mod h1:yYxEStHL7lt9uL+AbdWgW9gBumwieDoZCiB1f/0X0as=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/peterbourgon/ff/v3 v3.1.2/go.mod h1:XNJLY8EIl6MjMVjBS4F0+G0LYoAqs0DTa4rmHHukKDE=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sago35/go-bdf v0.0.0-20200313142241-6c17821c91c4/go.mod h1:rOebXGuMLsXhZAC6mF/TjxONsm45498ZyzVhel++6KM=
github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/soypat/cyw43439 v0.0.0-20240609122733-da9153086796/go.mod h1:1Otjk6PRhfzfcVHeWMEeku/VntFqWghUwuSQyivb2vE=
github.com/soypat/natiu-mqtt v0.5.1/go.mod h1:xEta+cwop9izVCW7xOx2W+ct9PRMqr0gNVkvBPnQTc4=
github.com/soypat/saleae v0.0.0-20230402180913-3584b7515dae/go.mod h1:9SV+w6E9YK/BePxdxYGXthkrRztHJCQlojWOjAxW3M4=
github.com/soypat/seqs v0.0.0-20240527012110-1201bab640ef/go.mod h1:oCVCNGCHMKoBj97Zp9znLbQ1nHxpkmOY9X+UAGzOxc8=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tdakkota/win32metadata v0.1.0/go.mod h1:77e6YvX0LIVW+O81fhWLnXAxxcyu/wdZdG7iwed7Fyk=
github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk=
github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899/go.mod h1:LU7Dw00NJ+N86QkeTGjMLNkYcEYMor6wTDpTCu0EaH8=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/wechatpay-apiv3/wechatpay-go v0.2.20 h1:gS8oFn1bHGnyapR2Zb4aqTV6l4kJWgbtqjCq6k1L9DQ=
github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.5.5/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
shylinux.com/x/community v0.0.3/go.mod h1:f/FIWPGaDLvnrpdpG5c9Ttj0hZzV51RtOOnW5IYk3IA=
shylinux.com/x/community v0.0.4/go.mod h1:JDPG8S21VOKn5hoa2YdCp87MMpYv+6777ut8dHopww0=
shylinux.com/x/community v0.0.6/go.mod h1:LHW7uwm+t5j2UVUuIkaUXNQ9u6z7i32a1intAl4Iuxg=
shylinux.com/x/community v0.0.8/go.mod h1:aMwANSS8R7JyeD+NAMCRivcb/ZIsl8doW8IwuThNTck=
shylinux.com/x/community v0.0.10/go.mod h1:76xFyUFOmvJ5OdjQp3vUTAG2oPjfTVfF+JghDLCFHEA=
shylinux.com/x/community v0.0.12 h1:qH10HfaNUiX7XH1vh4y34UA/PpM79vBXaRnRuXncLqQ=
shylinux.com/x/community v0.0.12/go.mod h1:29ixXxbhnlfn5tUNgRwyx4s1iNi39jq5KUlgab/Au5w=
shylinux.com/x/enterprise v0.0.1/go.mod h1:AHfHtTtR5AmSrCQqDh5gCU57h40V2UyA00nC1yEMsns=
shylinux.com/x/enterprise v0.0.3/go.mod h1:lo9wM4971wjrjrvuTD+KKzje6N7k3LV2+5c2DLuOXNM=
shylinux.com/x/enterprise v0.0.4/go.mod h1:sBLCMzaz612zlLlTFB93e302dYOy4aS856xaXqyBNJg=
shylinux.com/x/enterprise v0.0.5/go.mod h1:DiTiXP00MFDUR2trnsy5/qJ/w+JOOQC36YWloTGCZHs=
shylinux.com/x/enterprise v0.0.6/go.mod h1:YzUviyeUIFPd2BIvNkUGpmx6qRFbCvGSA6muxKQzbOM=
shylinux.com/x/enterprise v0.0.7/go.mod h1:v5FHdMRSdAJ2LhCWbJuI87nb329bQiv6W231AeT89T0=
shylinux.com/x/enterprise v0.0.8 h1:Kxbg0qFp1fcMgwZ9gEEQQz9MmnvHITIiqKXMwkk4At4=
shylinux.com/x/enterprise v0.0.8/go.mod h1:sxBDUPwUpFwAnix0gpeIunkSNFTZT6tdpo6mawmc9UM=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
shylinux.com/x/community v0.0.28 h1:/h7gthD8X6lVh1dDg3W3sBX4dpotbddfdGdR/BqBV4c=
shylinux.com/x/community v0.0.28/go.mod h1:MamBZhpO3+c5YISRJt4xnxa5VDBBstUR+9FnPQrhZMU=
shylinux.com/x/enterprise v0.0.17 h1:29VjNHt4YiPryQGNtVTnYqiXNHxau4EnkoUDzlxgB6Y=
shylinux.com/x/enterprise v0.0.17/go.mod h1:+DmZbYMykX5U65BJ7DYOcwFubslKa2b78DyRaqUYuH4=
shylinux.com/x/go-git/v5 v5.6.7 h1:WD5QSco7m3QooPCgdvQ6/GyGIFPun8C+hex5N41LYlk=
shylinux.com/x/go-git/v5 v5.6.7/go.mod h1:Qb0lA+uIrofZg8NQerhYcJHgGWixFqvS6p3aJ/L5Nlk=
shylinux.com/x/go-qrcode v0.0.3 h1:RMo+Vidbgq3HatLBj7DDXcTbTLFUwzis5K7TqBkD38U=
shylinux.com/x/go-qrcode v0.0.3/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po=
shylinux.com/x/go-sql-mysql v0.0.2/go.mod h1:lHjRMZz5Lii6U+49fhkbCWgsnL+yux54SYJYWqASN8Y=
shylinux.com/x/golang-story v0.0.24/go.mod h1:G0WEOJ0gCYR2tOs1ggyMBBrUMqJEgJjyvdFjN3VpNoM=
shylinux.com/x/golang-story v0.0.25/go.mod h1:X1ed1h9FojVVCB48z32GiCWObDkF5DCWlDB6cibvEnQ=
shylinux.com/x/golang-story v0.0.26 h1:CBP34sygh6Pc4nDZnM27RCJ2eTxENBS0qMRaamXMQeY=
shylinux.com/x/golang-story v0.0.26/go.mod h1:elamEBuhuzD1XFHpncYA3nAiuUlIKFBX+Y33Na5A+1c=
shylinux.com/x/ice v1.5.41/go.mod h1:hMhVMhUlsimwFcsPIH+J/tO8O8I0WEqg1NYyqdhULxE=
shylinux.com/x/ice v1.5.43/go.mod h1:m5PPsVula2aqFHp5kZX3talhwZ4u4zsLqqU0X3cesc0=
shylinux.com/x/ice v1.5.44/go.mod h1:/ze8UI3sUpdx8S/Qadr8xYRvLIri4P93Mkwi4b9EmEk=
shylinux.com/x/ice v1.5.45/go.mod h1:zQ6azXiRPHq1QE/buftQ1dRwfzgkPzZptXW083VfE40=
shylinux.com/x/ice v1.5.46/go.mod h1:l9ejEyDlVTeE6Dnj0sND9a7JixBkn9TdbZTkAdVUyTQ=
shylinux.com/x/ice v1.5.48 h1:jkr7SNkKIFI4xR7ns7H456wirGMY03KFwTj7hrUYxq8=
shylinux.com/x/ice v1.5.48/go.mod h1:aDG7yzDlX3NsWEoIjIoiV3sQPec4APZGbYsSJFtcI4I=
shylinux.com/x/icebergs v1.9.39/go.mod h1:rUqDj1pzd6uPj7+klEn+doqXiWlb/24/batRyBB5ppo=
shylinux.com/x/icebergs v1.9.41/go.mod h1:/BcFEB/6Dd70Owmb3wsA9NYShHQwmSH74xn9pNudRMg=
shylinux.com/x/icebergs v1.9.44/go.mod h1:/BcFEB/6Dd70Owmb3wsA9NYShHQwmSH74xn9pNudRMg=
shylinux.com/x/icebergs v1.9.45/go.mod h1:wM3PkomBSeASTekVjxuOP8Y28HYq84MxUZ3d5BZEN74=
shylinux.com/x/icebergs v1.9.46/go.mod h1:wM3PkomBSeASTekVjxuOP8Y28HYq84MxUZ3d5BZEN74=
shylinux.com/x/icebergs v1.9.48 h1:rROshbqjdiPtiZXS1pvUMBkZPFFRzANXaX7m9JRZVBo=
shylinux.com/x/icebergs v1.9.48/go.mod h1:wM3PkomBSeASTekVjxuOP8Y28HYq84MxUZ3d5BZEN74=
shylinux.com/x/mysql-story v0.6.14/go.mod h1:AvzKCyuN/zYMYRky3YjCsX1RLwCZFAL4zuQ5jzZidsM=
shylinux.com/x/mysql-story v0.6.16/go.mod h1:GTvoeL4r0PYEtZomPQgnndxSxHIZzPdrWkbQmplmn5o=
shylinux.com/x/mysql-story v0.6.18/go.mod h1:Am+fx/T9pEeUepoX0eoSM53Qu0xVcQKpLGdBNC+x43A=
shylinux.com/x/mysql-story v0.6.19/go.mod h1:1YCZtwNUgg26vlhecjnFiPWfUq5i7YfHC6nxy+waGuQ=
shylinux.com/x/mysql-story v0.6.20/go.mod h1:1YCZtwNUgg26vlhecjnFiPWfUq5i7YfHC6nxy+waGuQ=
shylinux.com/x/mysql-story v0.6.21/go.mod h1:HSWqYyKfvv2mctpEOfAf9zs81O+Z/swV000TN/GSgSY=
shylinux.com/x/mysql-story v0.6.22 h1:ZcpuIcp5ODktjd1yKRQGimQ/pZbwS3BYd5St7waaL1g=
shylinux.com/x/mysql-story v0.6.22/go.mod h1:tZMStD+Z9LbvGlkzqpjuDxg8Oc4jfTgPxdxY/cEbJdI=
shylinux.com/x/golang-story v0.0.32 h1:7xu28iREL2cuZzf80luJwI9BWptow+ME00L1lgyjmDI=
shylinux.com/x/golang-story v0.0.32/go.mod h1:NsI5fULu3q7o2b+VzZ5tiJ3+0pUTjE9DdQxa870htmw=
shylinux.com/x/ice v1.5.72/go.mod h1:ouTMN0stkJu1RGAQrMHrGj/BqDynyD1VV53shR9zQm4=
shylinux.com/x/ice v1.5.73/go.mod h1:uGI73gYkk+FiJt5qmy/aYhoKRJ4wobcJk3WrPGh8Waw=
shylinux.com/x/ice v1.5.74 h1:5hTPmchO79b1d2+/DwBDLiG2WkTL65G/hOEAcGJVeB8=
shylinux.com/x/ice v1.5.74/go.mod h1:/XAib8Ha+z6jzLRs2Pig+qxDx4C8dT8Vfaq2InJ/lkU=
shylinux.com/x/icebergs v1.9.73/go.mod h1:3Bdp3tjzw+hUKJF+kR8pfsrbjAf72DVZmCaE8/MPFtk=
shylinux.com/x/icebergs v1.9.75/go.mod h1:3Bdp3tjzw+hUKJF+kR8pfsrbjAf72DVZmCaE8/MPFtk=
shylinux.com/x/icebergs v1.9.76 h1:SHOTbiO+jh09GEFzoo8t8kmR1BCu+zkNCpdfxPCLeu0=
shylinux.com/x/icebergs v1.9.76/go.mod h1:3Bdp3tjzw+hUKJF+kR8pfsrbjAf72DVZmCaE8/MPFtk=
shylinux.com/x/mysql-story v0.6.32 h1:Q274WFJ09ocnf8nhlQnKr02FMMdPYBLWqu2IjTVqGiM=
shylinux.com/x/mysql-story v0.6.32/go.mod h1:8HCeDUV6ghaIeJD1IEhSeSOfVC9wEI93y2G9QBLtJJY=
shylinux.com/x/toolkits v0.7.10/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.13/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.14/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.15 h1:E8+tCRfAe7L5z3EfyHA3Zf+0czxjHfOw40q3158Rsw4=
shylinux.com/x/toolkits v1.0.15/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.19 h1:Nrx0xYRc5ph1WS66EZ1hJUCe+2FdSWQ4QP6tBlguikQ=
shylinux.com/x/toolkits v1.0.19/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/websocket v0.0.4 h1:AJpwblePoOpiE6C8NrvgNYpKTotXMLrDDX2chTvx44Q=
shylinux.com/x/websocket v0.0.4/go.mod h1:3UGWkjTu3ie5NAZen7J+uLPBrO7DFeKloj6Jxo13Oiw=
tinygo.org/x/bluetooth v0.10.0/go.mod h1:t/Vm2a/rslsBoqFQKCBsWQw/cmRicQq+8Tl3tj5RCRI=
tinygo.org/x/drivers v0.14.0/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI=
tinygo.org/x/drivers v0.15.1/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI=
tinygo.org/x/drivers v0.16.0/go.mod h1:uT2svMq3EpBZpKkGO+NQHjxjGf1f42ra4OnMMwQL2aI=
tinygo.org/x/drivers v0.19.0/go.mod h1:uJD/l1qWzxzLx+vcxaW0eY464N5RAgFi1zTVzASFdqI=
tinygo.org/x/drivers v0.25.0/go.mod h1:v+mXaA4cgpz/YZJ3ZPm/86bYQJAXTaYtMkHlVwbodbw=
tinygo.org/x/drivers v0.26.1-0.20230922160320-ed51435c2ef6/go.mod h1:X7utcg3yfFUFuKLOMTZD56eztXMjpkcf8OHldfTBsjw=
tinygo.org/x/tinyfont v0.2.1/go.mod h1:eLqnYSrFRjt5STxWaMeOWJTzrKhXqpWw7nU3bPfKOAM=
tinygo.org/x/tinyfont v0.3.0/go.mod h1:+TV5q0KpwSGRWnN+ITijsIhrWYJkoUCp9MYELjKpAXk=
tinygo.org/x/tinyfont v0.4.0/go.mod h1:7nVj3j3geqBoPDzpFukAhF1C8AP9YocMsZy0HSAcGCA=
tinygo.org/x/tinyfs v0.1.0/go.mod h1:ysc8Y92iHfhTXeyEM9+c7zviUQ4fN9UCFgSOFfMWv20=
tinygo.org/x/tinyterm v0.1.0/go.mod h1:/DDhNnGwNF2/tNgHywvyZuCGnbH3ov49Z/6e8LPLRR4=
tinygo.org/x/tinyterm v0.3.0/go.mod h1:F1pQjxEwNZQIc5czeJSBtk57ucEvbR4u7vHaLhWhHtg=

35
src/dashboard/cleanup.go Normal file
View File

@ -0,0 +1,35 @@
package dashboard
import (
"shylinux.com/x/ice"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/community/src/api"
"shylinux.com/x/operation/src/dashboard/model"
)
type cleanup struct {
Tables
portal Portal
order string `data:"3"`
role string `data:"leader"`
placeTrash string `name:"placeTrash" help:"清理"`
}
func (s cleanup) PlaceTrash(m *ice.Message, arg ...string) {
m.Cmd("").Table(func(value ice.Maps) {
if value[model.AUTH_UID] != "" {
s.AutoCmd(m, api.RENZHENGSHOUQUAN_PORTAL, s.portal.PlaceTrash, kit.Dict(model.UID, value[model.AUTH_UID]))
}
s.AutoCmd(m, value[model.INDEX], s.portal.PlaceTrash, value)
})
}
func (s cleanup) List(m *ice.Message, arg ...string) {
m.Cmd("service").Table(func(value ice.Maps) {
s.AutoCmdy(m, value[model.INDEX], s.portal.PlaceCheck)
})
m.Action(s.PlaceTrash)
m.DisplayTable()
}
func init() { ice.TeamCtxCmd(cleanup{}) }

View File

@ -14,6 +14,7 @@ import (
type dashboard struct {
Table
order string `data:"1"`
role string `data:"leader"`
fields string `data:"dashboard_type,host,port,username,database"`
config string `name:"config host* port* username* password* database*" role:"leader"`
}
@ -23,12 +24,12 @@ func (s dashboard) Config(m *ice.Message, arg ...string) {
s.UserPlaceInit(m)
}
func (s dashboard) Schema(m *ice.Message, arg ...string) {
m.Display("/plugin/table.js")
s.Show(m, s.Open(m).Raw(`
select TABLE_SCHEMA,TABLE_NAME,TABLE_ROWS,DATA_LENGTH,INDEX_LENGTH from information_schema.TABLES
where TABLE_SCHEMA != 'mysql' AND TABLE_SCHEMA != 'information_schema' AND TABLE_SCHEMA != 'performance_schema'
order by DATA_LENGTH desc
`))
m.DisplayTable()
}
func (s dashboard) List(m *ice.Message, arg ...string) {
if len(arg) == 0 {

View File

@ -10,8 +10,10 @@ const (
TITLE = "title"
CONTENT = "content"
CREATED_AT = "created_at"
DELETED_AT = "deleted_at"
USER_UID = "user_uid"
USER_DASHBOARD_ROLE = "user_dashboard_role"
AUTH_UID = "auth_uid"
DASHBOARD_UID = "dashboard_uid"
DASHBOARD_NAME = "dashboard_name"
DASHBOARD_TYPE = "dashboard_type"
@ -26,6 +28,7 @@ const (
QUERY = "query"
VALUE = "value"
SCORE = "score"
INDEX = "index"
)
type UserDashboard struct {

View File

@ -1,10 +1,11 @@
{
"portal": "数据分析",
"dashboard": "连接配置", "summary": "数据汇总",
"dashboard": "连接配置", "summary": "数据汇总", "cleanup": "数据清理",
"config": "配置", "schema": "概况",
"icons": {
"dashboard": "https://img.icons8.com/officel/80/data-configuration.png",
"summary": "https://img.icons8.com/officel/80/statistics.png"
"summary": "https://img.icons8.com/officel/80/statistics.png",
"cleanup": "https://img.icons8.com/officel/80/data-configuration.png"
},
"input": {
"My Dashboard": "我的数据",

View File

@ -11,6 +11,7 @@ type summary struct {
Table
dashboard dashboard
order string `data:"2"`
role string `data:"leader,worker"`
create string `name:"create space* index* query field title score unit" role:"leader"`
modify string `name:"modify space* index* query field title score unit" role:"leader"`
remove string `name:"remove" role:"leader"`

8
src/document/content.shy Normal file
View File

@ -0,0 +1,8 @@
spark project "云时代的新型操作系统,既要完全自给自足,又要任意互联互通" `
<b>产品迭代:</b>
<b>软件开发:</b>
<b>系统运维:</b>
<b>文件存储:</b>
<b>数据分析:</b>
`
spark product

11
src/document/index.shy Normal file
View File

@ -0,0 +1,11 @@
navmenu `
"{{ .Title }}" /
_
"下 载" download/
"文 档" started/
"开 发" development/
_
"应 用" "https://web.shylinux.com/s/20240903-operation"
"源 码" "https://git.shylinux.com/web/operation"
"社 区" "https://bbs.shylinux.com"
`

View File

@ -11,3 +11,8 @@ import (
)
func main() { print(ice.Run()) }
func init() {
ice.Info.CodeMain = "src/production/portal.go"
ice.Info.NodeMain = "web.team.production.portal"
}

View File

@ -1,3 +1,8 @@
title "云研发"
field web.team.operation.portal
refer `
官网 https://web.shylinux.com
源码 https://git.shylinux.com/web/operation
应用 https://web.shylinux.com/s/20240903-operation
`
field web.code.mysql.client
field web.code.mysql.query args `mysql operation`

103
src/operation/cluster.go Normal file
View File

@ -0,0 +1,103 @@
package operation
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
"2025-dev.shylinux.com/x/20250215-cluster/src/travel"
"shylinux.com/x/operation/src/operation/model"
)
type Cluster struct {
Table
travel travel.Travel
order string `data:"1"`
fields string `data:"title,content,space,total,stock,price,cluster_status"`
payfor string `name:"payfor" help:"购买" style:"notice" role:"leader"`
modify string `name:"modify title content price" style:"danger"`
}
func (s Cluster) Scan(m *ice.Message, arg ...string) {
m.Cmd(s.travel, s.travel.Concurrent, ice.GetTypeMod(s.travel), ice.GetTypeKey(s.travel)).Table(func(value ice.Maps) {
s.InsertIfNeed(m, web.SPACE, value[web.SPACE])
})
m.Cmd("").Table(func(value ice.Maps) { s.ScanService(m.Options(value)) })
m.ProcessRefresh()
}
func (s Cluster) List(m *ice.Message, arg ...string) {
if len(arg) < 2 {
if m.IsTech() {
s.Select(m)
} else {
s.Select(m, model.STATUS, kit.Format(ClusterOnline))
}
} else {
s.SelectDetail(m, model.UID, arg[1])
}
if m.Length() == 0 {
if m.IsTech() {
m.EchoInfoButton("请扫描集群", s.Scan)
} else {
m.Echo("请联系「平台管理员」部署集群").Action()
}
} else {
if m.Display(""); m.IsTech() {
m.Table(func(value ice.Maps) {
if ClusterStatus(kit.Int(value[model.CLUSTER_STATUS])) == ClusterOnline && kit.Int(value[model.STOCK]) > 0 {
m.PushButton(s.Payfor, s.ScanService, s.Offline, s.Modify)
} else {
m.PushButton(s.ScanService, s.Online, s.Modify)
}
}).Action(s.Scan)
} else if s.IsLeader(m) {
m.Table(func(value ice.Maps) {
if ClusterStatus(kit.Int(value[model.CLUSTER_STATUS])) == ClusterOnline && kit.Int(value[model.STOCK]) > 0 {
m.PushButton(s.Payfor)
} else {
m.PushButton()
}
}).Action()
} else {
m.PushAction().Action()
}
}
if len(arg) == 2 && m.IsTech() {
m.EchoIFrame(web.S(m.Append(web.SPACE)))
}
}
func (s Cluster) Payfor(m *ice.Message, arg ...string) {
m.Cmdy(Gateway{}, s.Payfor, arg, kit.Dict(model.CLUSTER_UID, m.Option(model.UID)))
}
func (s Cluster) ScanService(m *ice.Message, arg ...string) {
m.Cmdy(Gateway{}, s.Scan, arg, kit.Dict(model.CLUSTER_UID, m.Option(model.UID))).ProcessRefresh()
s.Update(m, m.AppendSimple(model.TOTAL, model.STOCK), m.OptionSimple(model.UID)...)
}
func (s Cluster) Offline(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(ClusterOffline)})
s.RecordEventWithName(m, "")
}
func (s Cluster) Online(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(ClusterOnline)})
s.RecordEventWithName(m, "")
}
func (s Cluster) Modify(m *ice.Message, arg ...string) {
s.Update(m, s.TransPrice(m, arg))
s.RecordEventWithName(m, "")
}
func init() { ice.TeamCtxCmd(Cluster{}) }
type ClusterStatus int
const (
ClusterOffline ClusterStatus = iota
ClusterOnline
)
var ClusterStatusList = map[ClusterStatus]string{
ClusterOffline: "offline",
ClusterOnline: "online",
}
func (s ClusterStatus) String() string { return ClusterStatusList[s] }

9
src/operation/cluster.js Normal file
View File

@ -0,0 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title||value.space, value.price+" 元/月", can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value)]},
{view: html.OUTPUT, list: [value.content]},
] })
},
})

View File

@ -20,6 +20,10 @@ func (s Table) Inputs(m *ice.Message, arg ...string) {
s.InputsListRole(m, UserCloudRoleList, arg...)
case model.CLOUD_TYPE:
s.InputsList(m, CloudTypeList, arg...)
case model.GATEWAY_UID:
m.Cmdy(Gateway{}, m.Option(model.CLOUD_UID)).Cut(model.UID, model.TITLE)
m.RenameAppend(model.UID, arg[0], model.TITLE, model.NAME)
m.DisplayInputKeyNameIconTitle()
default:
s.Table.Inputs(m, arg...)
}
@ -31,6 +35,12 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message {
value = UserCloudRole(kit.Int(value)).String()
case model.CLOUD_TYPE:
value = CloudType(kit.Int(value)).String()
case model.CLUSTER_STATUS:
value = ClusterStatus(kit.Int(value)).String()
case model.TEMPLATE_STATUS:
value = TemplateStatus(kit.Int(value)).String()
case model.PRICE:
value = kit.Format("%.2f", kit.Float(value)/100)
}
return value
})

89
src/operation/gateway.go Normal file
View File

@ -0,0 +1,89 @@
package operation
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
"2025-dev.shylinux.com/x/20250211-service/src/gateway"
"2025-dev.shylinux.com/x/20250215-cluster/src/travel"
"shylinux.com/x/operation/src/operation/model"
)
type Gateway struct {
Table
cluster Cluster
travel travel.Travel
gateway gateway.Gateway
order string `data:"3"`
fields string `data:"title,content,space,cluster_uid,user_uid"`
payfor string `name:"payfor" help:"购买" style:"notice" role:"leader"`
createProject string `name:"createProject name* repos binary" help:"创建" style:"notice" role:"worker"`
scanProject string `name:"scanProject" help:"扫描" role:"worker"`
open string `name:"open" role:"leader"`
modify string `name:"modify title content" style:"danger" role:"leader"`
}
func (s Gateway) List(m *ice.Message, arg ...string) {
if s.ValueList(m, arg); s.IsLeader(m) {
m.PushAction(s.CreateProject, s.ScanProject, s.Open, s.Modify)
} else {
m.PushAction()
}
if m.Action(); m.Length() == 0 {
if m.SetResult(); s.IsLeader(m) {
m.Echo("请到「云集群」购买主机")
} else if s.IsWorker(m) {
m.Echo("请联系「管理员」购买主机")
} else {
m.Echo("请等待「管理员」购买主机")
}
} else {
s.Fields(m, model.UID, s.KeyAS(s.cluster, model.SPACE)).SelectJoin(m, s.cluster, s.Keys(s.cluster, model.SPACE)).Display("")
}
if len(arg) == 2 && s.IsLeader(m) {
m.EchoIFrame(web.S(s.space(m.Spawn().Options(model.CLOUD_UID, arg[0], model.UID, arg[1]))))
}
}
func (s Gateway) CreateProject(m *ice.Message, arg ...string) {
m.Cmdy(project{}, s.Create, arg, model.GATEWAY_UID, m.Option(model.UID), kit.Dict(web.SPACE, s.space(m.Spawn()))).ProcessRefresh()
}
func (s Gateway) ScanProject(m *ice.Message, arg ...string) {
m.Cmdy(project{}, s.Scan, kit.Dict(model.GATEWAY_UID, m.Option(model.UID), web.SPACE, s.space(m.Spawn()))).ProcessRefresh()
}
func (s Gateway) Open(m *ice.Message, arg ...string) {
m.ProcessOpen(m.Options(ice.MSG_USERPOD, "").MergePodCmd(s.space(m.Spawn()), web.ADMIN))
}
func (s Gateway) Modify(m *ice.Message, arg ...string) {
s.Update(m, arg, m.OptionSimple(model.CLOUD_UID, model.UID)...)
s.RecordEventWithName(m, "")
}
func init() { ice.TeamCtxCmd(Gateway{}) }
func (s Gateway) Payfor(m *ice.Message, arg ...string) {
s.Transaction(m, func() {
msg := m.Spawn()
if msg = s.Orders(msg, mdb.ID).Limit(msg, 1).SelectForUpdate(msg, "cluster_uid = ? AND (cloud_uid IS NULL OR cloud_uid = '')", m.Option(model.CLUSTER_UID)); msg.Length() == 0 {
m.Echo("主机不够用啦!请等待平台管理员添加。")
} else {
m.Option(model.TITLE, "我的云主机")
s.Update(m, m.OptionSimple(model.CLOUD_UID, model.USER_UID, model.TITLE), msg.AppendSimple(model.UID)...)
s.RecordEventWithName(m.Options(model.UID, msg.Append(model.UID)), "")
s.SendMessage(s.GetCommandUID(m), "", "")
}
})
}
func (s Gateway) Scan(m *ice.Message, arg ...string) {
m.Cmd(web.SPACE, m.Option(web.SPACE), s.travel, s.travel.Concurrent, ice.GetTypeMod(s.gateway), ice.GetTypeKey(s.gateway)).Table(func(value ice.Maps) {
s.InsertIfNeed(m, web.SPACE, value[web.SPACE], model.CLUSTER_UID, m.Option(model.CLUSTER_UID))
})
s.Fields(m, "count(*) AS total").Select(m, model.CLUSTER_UID, m.Option(model.CLUSTER_UID))
s.Fields(m, "count(*) AS stock").Select(m, "cluster_uid = ? AND (cloud_uid IS NULL OR cloud_uid = '')", m.Option(model.CLUSTER_UID))
}
func (s Gateway) space(m *ice.Message, arg ...string) string {
s.Tables(m, s.cluster).Fields(m, s.Key(s, web.SPACE), s.KeyAS(s.cluster, web.SPACE))
s.Select(m, kit.Simple(m.OptionSimple(model.CLOUD_UID), s.Key(s, model.UID), m.Option(model.UID))...)
return kit.Keys(m.Append(model.CLUSTER_SPACE), m.Append(web.SPACE))
}

View File

@ -1,7 +1,7 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title]},
{view: html.TITLE, list: [value.title||value.space, can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.OUTPUT, list: [value.content]},
] })

View File

@ -7,13 +7,26 @@ const (
NAME = "name"
INFO = "info"
TYPE = "type"
ROLE = "role"
STATUS = "status"
TOTAL = "total"
STOCK = "stock"
PRICE = "price"
SPACE = "space"
TITLE = "title"
CONTENT = "content"
USER_UID = "user_uid"
USER_CLOUD_ROLE = "user_cloud_role"
CLOUD_UID = "cloud_uid"
CLOUD_TYPE = "cloud_type"
RELEASE_UID = "release_uid"
CLUSTER_UID = "cluster_uid"
CLUSTER_SPACE = "cluster_space"
CLUSTER_STATUS = "cluster_status"
TEMPLATE_STATUS = "template_status"
GATEWAY_UID = "gateway_uid"
GATEWAY_SPACE = "gateway_space"
PROJECT_UID = "project_uid"
PROJECT_NAME = "project_name"
)
type UserCloud struct {
@ -24,9 +37,44 @@ type Cloud struct {
db.ModelPlace
CompanyUID string `gorm:"type:char(32);index"`
}
type Release struct {
type Cluster struct {
db.ModelContent
CloudUID string `gorm:"type:char(32);index"`
Space string `gorm:"type:varchar(64);index"`
Total int `gorm:"default:0"`
Stock int `gorm:"default:0"`
Price int `gorm:"default:0"`
Status uint8 `gorm:"default:0"`
}
type Template struct {
db.ModelNameInfo
Title string `gorm:"type:varchar(64)"`
Icons string `gorm:"type:varchar(255)"`
Repos string `gorm:"type:varchar(255)"`
Binary string `gorm:"type:varchar(255)"`
Status uint8 `gorm:"default:0"`
}
type Gateway struct {
db.ModelContent
Space string `gorm:"type:varchar(64)"`
CloudUID string `gorm:"type:char(32);index"`
ClusterUID string `gorm:"type:char(32);index"`
}
type Project struct {
db.ModelNameInfo
Icons string `gorm:"type:varchar(255)"`
Repos string `gorm:"type:varchar(255)"`
Binary string `gorm:"type:varchar(255)"`
CloudUID string `gorm:"type:char(32);index"`
GatewayUID string `gorm:"type:char(32);index"`
}
type Product struct {
db.ModelNameInfo
Icon string `gorm:"type:varchar(255)"`
Index string `gorm:"type:varchar(128)"`
CloudUID string `gorm:"type:char(32);index"`
ProjectUID string `gorm:"type:char(32);index"`
}
func init() { db.CmdModels("", &UserCloud{}, &Cloud{}, &Release{}) }
func init() {
db.CmdModels("", &UserCloud{}, &Cloud{}, &Cluster{}, &Gateway{}, &Template{}, &Project{}, &Product{})
}

View File

@ -1,14 +1,31 @@
{
"portal": "系统运维",
"release": "发布",
"cluster": "云集群", "gateway": "云主机", "template": "云模板", "project": "云项目", "product": "云服务",
"scanService": "扫描", "offline": "下架", "online": "上架",
"style": {
"offline": "danger"
},
"icons": {
"release": "https://img.icons8.com/officel/80/activity-grid.png"
"cluster": "activity-grid.png",
"gateway": "activity-grid.png",
"template": "activity-grid.png",
"project": "activity-grid.png",
"product": "activity-grid.png"
},
"input": {
"My Cloud": "我的系统",
"user_cloud_role": "用户角色",
"cloud_name": "系统名称",
"cloud_type": "系统类型"
"cloud_type": "系统类型",
"cloud_space": "集群空间",
"cluster_status": "集群状态",
"cluster_space": "集群空间",
"template_status": "模板状态",
"gateway_uid": "云主机",
"gateway_title": "云主机",
"gateway_space": "主机空间",
"project_name": "项目名称",
"stock": "库存"
},
"value": {
"user_cloud_role": {

59
src/operation/product.go Normal file
View File

@ -0,0 +1,59 @@
package operation
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/community/src/api"
"shylinux.com/x/operation/src/operation/model"
)
type product struct {
Table
cluster Cluster
gateway Gateway
project project
order string `data:"5"`
fields string `data:"name,icon,index,project_uid"`
open string `name:"open" style:"notice" role:"void"`
}
func (s product) Scan(m *ice.Message, arg ...string) {
m.Cmd(web.SPACE, m.Option(web.SPACE), api.GONGANXITONG_PORTAL)
m.Cmd(web.SPACE, m.Option(web.SPACE), api.GONGANXITONG_SERVICE).Table(func(value ice.Maps) {
s.InsertIfNeed(m.Options(ctx.INDEX, value[ctx.INDEX]), m.OptionSimple(model.CLOUD_UID, model.PROJECT_UID, ctx.INDEX)...)
s.Update(m, kit.Dict(mdb.NAME, value[mdb.NAME], mdb.ICON, value[mdb.ICON]), m.OptionSimple(model.CLOUD_UID, model.PROJECT_UID, ctx.INDEX)...)
})
}
func (s product) List(m *ice.Message, arg ...string) {
if s.ValueList(m, arg); s.IsLeader(m) {
m.PushAction(s.Open, s.Remove)
} else {
m.PushAction(s.Open)
}
if m.Length() == 0 {
m.SetResult().Echo("请到「云项目」扫描服务")
} else {
m.Display("")
}
s.Fields(m, model.UID, s.Keys(s.gateway, model.UID), s.KeyAS(s.project, mdb.NAME)).SelectJoin(m, s.project, s.Keys(s.project, mdb.NAME), s.Keys(s.gateway, model.UID))
s.Fields(m, model.UID, s.Keys(s.cluster, model.UID), s.KeyAS(s.gateway, model.TITLE), s.KeyAS(s.gateway, model.SPACE)).SelectJoin(m, s.gateway, s.Keys(s.cluster, model.UID), s.Keys(s.gateway, model.SPACE), s.Keys(s.gateway, model.TITLE))
s.Fields(m, model.UID, s.KeyAS(s.cluster, model.SPACE)).SelectJoin(m, s.cluster, s.Keys(s.cluster, model.SPACE))
if len(arg) == 2 {
m.EchoIFrame(web.S(kit.Keys(m.Append(model.CLUSTER_SPACE), m.Append(model.GATEWAY_SPACE), m.Append(model.PROJECT_NAME))))
}
}
func (s product) Open(m *ice.Message, arg ...string) {
m.ProcessOpen(m.Options(ice.MSG_USERPOD, "").MergePodCmd(s.space(m.Spawn()), m.Option(ctx.INDEX)))
}
func init() { ice.TeamCtxCmd(product{}) }
func (s product) space(m *ice.Message, arg ...string) string {
s.Tables(m, s.project, s.gateway, s.cluster).Fields(m, s.Key(s.project, mdb.NAME), s.KeyAS(s.gateway, web.SPACE), s.KeyAS(s.cluster, web.SPACE))
s.Select(m, kit.Simple(s.Key(s, model.CLOUD_UID), m.Option(model.CLOUD_UID), s.Key(s, model.UID), m.Option(model.UID))...)
return kit.Keys(m.Append(model.CLUSTER_SPACE), m.Append(model.GATEWAY_SPACE), m.Append(mdb.NAME))
}

12
src/operation/product.js Normal file
View File

@ -0,0 +1,12 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) {
value.icon = can.misc.ResourceIcons(can, value.icon, can.core.Keys(value.cluster_space, value.gateway_space, value.project_name))
return [
{view: html.TITLE, list: [value.name, can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.gateway_title]},
{view: html.OUTPUT, list: [value.info]},
]
})
},
})

75
src/operation/project.go Normal file
View File

@ -0,0 +1,75 @@
package operation
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/operation/src/operation/model"
)
type project struct {
Table
cluster Cluster
gateway Gateway
order string `data:"4"`
fields string `data:"name,icons,repos,binary,gateway_uid"`
create string `name:"create name* icons repos binary" style:"notice" role:"worker"`
scanProduct string `name:"scanProduct" help:"扫描" role:"worker"`
open string `name:"open" role:"worker"`
}
func (s project) Create(m *ice.Message, arg ...string) {
if s.Select(m.Spawn(), m.OptionSimple(model.CLOUD_UID, model.GATEWAY_UID, mdb.NAME)...).Length() > 0 {
return
}
msg := m.Cmd(web.SPACE, m.Option(web.SPACE), web.DREAM, mdb.CREATE, arg, kit.Dict(ice.MSG_USERROLE, aaa.TECH))
s.Insert(m, kit.Simple(arg, msg.OptionSimple(model.CLOUD_UID, model.GATEWAY_UID, mdb.NAME))...)
s.SendMessage(s.GetCommandUID(m), "", "", m.Option(model.CLOUD_UID), m.Result())
s.RecordEventWithName(m, "")
}
func (s project) Scan(m *ice.Message, arg ...string) {
m.Cmd(web.SPACE, m.Option(web.SPACE), web.DREAM).Table(func(value ice.Maps) {
if m.Option(mdb.NAME, value[mdb.NAME]); value[mdb.TYPE] == web.WORKER {
s.InsertIfNeed(m, m.OptionSimple(model.CLOUD_UID, model.GATEWAY_UID, mdb.NAME)...)
}
s.Update(m, kit.Dict(nfs.REPOS, value[nfs.REPOS], nfs.BINARY, value[nfs.BINARY]), m.OptionSimple(model.CLOUD_UID, model.GATEWAY_UID, mdb.NAME)...)
})
}
func (s project) List(m *ice.Message, arg ...string) {
if s.ValueList(m, arg); s.IsLeader(m) {
m.PushAction(s.ScanProduct, s.Open, s.Remove)
} else if s.IsWorker(m) {
m.PushAction(s.ScanProduct, s.Open)
} else {
m.PushAction()
}
if m.Action(); m.Length() == 0 {
m.SetResult().Echo("请到「云主机」创建项目")
} else {
s.Fields(m, model.UID, s.KeyAS(s.gateway, model.TITLE), s.KeyAS(s.gateway, model.SPACE), s.Keys(s.cluster, model.UID))
s.SelectJoin(m, s.gateway, s.Keys(s.gateway, model.TITLE), s.Keys(s.gateway, model.SPACE), s.Keys(s.cluster, model.UID))
s.Fields(m, model.UID, s.KeyAS(s.cluster, model.SPACE)).SelectJoin(m, s.cluster, s.Keys(s.cluster, model.SPACE))
m.Display("")
}
if len(arg) == 2 && s.IsWorker(m) {
m.EchoIFrame(web.S(s.space(m.Spawn().Options(model.CLOUD_UID, arg[0], model.UID, arg[1]))))
}
}
func (s project) ScanProduct(m *ice.Message, arg ...string) {
m.Cmdy(product{}, s.Scan, kit.Dict(model.PROJECT_UID, m.Option(model.UID), web.SPACE, s.space(m))).ProcessRefresh()
}
func (s project) Open(m *ice.Message, arg ...string) {
m.ProcessOpen(m.Options(ice.MSG_USERPOD, "").MergePodCmd(s.space(m), web.ADMIN))
}
func init() { ice.TeamCtxCmd(project{}) }
func (s project) space(m *ice.Message, arg ...string) string {
s.Tables(m, s.gateway, s.cluster).Fields(m, s.Key(s, mdb.NAME), s.KeyAS(s.gateway, web.SPACE), s.KeyAS(s.cluster, web.SPACE))
s.Select(m, kit.Simple(s.Key(s, model.CLOUD_UID), m.Option(model.CLOUD_UID), s.Key(s, model.UID), m.Option(model.UID))...)
return kit.Keys(m.Append(model.CLUSTER_SPACE), m.Append(model.GATEWAY_SPACE), m.Append(mdb.NAME))
}

9
src/operation/project.js Normal file
View File

@ -0,0 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.name, can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.gateway_title]},
{view: html.OUTPUT, list: [value.binary||value.repos]},
] })
},
})

View File

@ -1,14 +0,0 @@
package operation
import "shylinux.com/x/ice"
type release struct {
Table
fields string `data:"title,content,user_uid"`
create string `name:"create title* content*" role:"leader"`
remove string `name:"remove" role:"leader"`
}
func (s release) List(m *ice.Message, arg ...string) { s.ValueList(m, arg).Display("") }
func init() { ice.TeamCtxCmd(release{}) }

6
src/operation/studio.css Normal file
View File

@ -0,0 +1,6 @@
// $body { --action-height:64px; }
// $fieldset>div.header>div { line-height:54px; }
// $option>div.item.icon { line-height:58px; }
$project div.item:not(.text) { padding:10px; }
// $project div.item:hover { background-color:transparent; }
// $project div.item.select { background-color:transparent; }

56
src/operation/studio.go Normal file
View File

@ -0,0 +1,56 @@
package operation
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/operation/src/operation/model"
)
type studio struct {
Tables
cluster Cluster
list string `name:"list list"`
gateway string `name:"gateway" role:"void"`
project string `name:"project" role:"void"`
product string `name:"product" role:"void"`
}
func (s studio) List(m *ice.Message, arg ...string) {
m.Cmdy(s.PrefixPortal(m)).Action().Display("").DisplayCSS("")
}
func (s studio) Gateway(m *ice.Message, arg ...string) {
if len(arg) < 3 {
m.Cmdy(m.Prefix(m.ActionKey()), arg[0])
} else {
m.Cmdy(web.SPACE, s.space(m, arg, model.CLUSTER_SPACE, model.SPACE), arg[2:])
}
}
func (s studio) Project(m *ice.Message, arg ...string) {
if len(arg) < 3 {
m.Cmdy(m.Prefix(m.ActionKey()), s.Select, model.CLOUD_UID, arg[0], model.GATEWAY_UID, arg[1])
} else {
m.Cmdy(web.SPACE, s.space(m, arg, model.CLUSTER_SPACE, model.GATEWAY_SPACE, model.NAME), arg[2:])
}
}
func (s studio) Product(m *ice.Message, arg ...string) {
if len(arg) < 3 {
m.Cmdy(m.Prefix(m.ActionKey()), s.Select, model.CLOUD_UID, arg[0], model.PROJECT_UID, arg[1])
} else {
m.Cmdy(web.SPACE, s.space(m, arg, model.CLUSTER_SPACE, model.GATEWAY_SPACE, model.PROJECT_NAME), arg[2:])
}
}
func init() { ice.TeamCtxCmd(studio{}) }
func (s studio) space(m *ice.Message, arg []string, args ...string) string {
if s.UserPlaceRole(m); s.IsWorker(m) {
m.Option(ice.MSG_USERROLE, aaa.TECH)
}
space := []ice.Any{}
msg := m.Cmd(m.Prefix(m.ActionKey()), arg[0], arg[1])
kit.For(args, func(key string) { space = append(space, msg.Append(key)) })
return m.Option(ice.MSG_USERPOD, kit.Keys(space...))
}

98
src/operation/studio.js Normal file
View File

@ -0,0 +1,98 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.onmotion.hidden(can, can._status)
can.ui = can.onappend.layout(can), can.onimport.place(can, msg)
},
place: function(can, msg) {
msg.Table(function(value) {
can.onimport.item(can, {icon: "bi bi-phone", name: value.cloud_name, _hash: [value.cloud_uid.slice(0, 12)]}, function(event, item, show, target) { can.db.cloud_uid = value.cloud_uid
show === undefined && can.runAction(event, "gateway", [value.cloud_uid], function(msg) {
can.onimport.gateway(can, msg, target, value.cloud_uid)
})
return true
}, function(event, item, target) {
return {meta: {
open: function() { can.user.open("/s/"+can.misc.Search(can, ice.POD)+"/c/"+"web.team.operation.portal"+"?cloud_uid="+value.cloud_uid) },
}}
})
})
},
gateway: function(can, msg, target, cloud_uid) {
can.onimport.itemlist(can, msg.Table(function(value) {
return {icon: "bi bi-window-desktop", name: value.title, _hash: target._item._hash.concat([value.space.slice(0, 12)]), action: "gateway", cloud_uid: cloud_uid, uid: value.uid, space: can.core.Keys(value.cluster_space, value.space)}
}), function(event, item, show, target) { can.db.gateway_uid = item.uid
show === undefined && can.runAction(event, "project", [cloud_uid, item.uid], function(msg) {
if (msg.Length() == 0) {
can.onimport.plugin(can, item, target)
} else {
can.onimport.project(can, msg, target, cloud_uid)
}
})
return true
}, function(event, item, target) {
return can.onimport.contexts(can, item, target)
}, target)
},
project: function(can, msg, target, cloud_uid) {
can.onimport.itemlist(can, msg.Table(function(value) {
return {icon: "bi bi-window-sidebar", name: value.name, _hash: target._item._hash.concat([value.name]), action: "project", cloud_uid: cloud_uid, uid: value.uid, space: can.core.Keys(target._item.space, value.name)}
}), function(event, item, show, target) { can.db.project_uid = item.uid
show === undefined && can.runAction(event, "product", [cloud_uid, item.uid], function(msg) {
if (msg.Length() == 0) {
can.onimport.plugin(can, item, target)
} else {
can.onimport.product(can, msg, target, cloud_uid)
}
})
return true
}, function(event, item, target) {
return can.onimport.contexts(can, item, target)
}, target)
},
product: function(can, msg, target, cloud_uid) {
can.onimport.itemlist(can, msg.Table(function(value) {
return {icon: "bi bi-phone", name: value.name, _hash: target._item._hash.concat([value.index]), action: "product", cloud_uid: cloud_uid, uid: value.uid, space: target._item.space, index: value.index}
}), function(event, item, show, target) { can.db.product_uid = item.uid
can.onimport.plugin(can, item, target)
}, function(event, item, target) {
return {meta: {
open: function() { can.user.open("/s/"+item.space+"/c/"+item.index) },
}}
}, target)
},
contexts: function(can, item, target) {
return {meta: {
portal: function() { can.onappend.plugin(can._root.Action, {index: web.CHAT_IFRAME, args: "/s/"+item.space+"/c/portal", style: html.FLOAT, title: item.name}) },
desktop: function() { can.onimport.plugin(can, item, target, web.DESKTOP) },
admin: function() { can.onappend.plugin(can._root.Action, {index: web.CHAT_IFRAME, args: "/s/"+item.space+"/c/admin", style: html.FLOAT, title: item.name}) },
word: function() { can.onimport.plugin(can, item, target, web.WORD) },
vimer: function() { can.onimport.plugin(can, item, target, web.VIMER) },
runtime: function() { can.onimport.plugin(can, item, target, cli.RUNTIME) },
xterm: function() { can.onimport.plugin(can, item, target, cli.XTERM) },
open: function() { can.user.open("/s/"+item.space) },
}}
},
plugin: function(can, item, target, index) {
if (!index && !item.index) {
for (var i = 0; i < item._hash.length; i++) { if (item._hash[i] != can.db.hash[i]) { break } }
if (i == item._hash.length) { index = can.db.hash[i] }
} if (index) { can.onexport.hash(can, item._hash.concat([index])) }
index = index||item.index||web.DESKTOP, item.plugin = item.plugin||{}
can.onimport.tabsCache(can, item.plugin[index] = item.plugin[index]||{name: item.name+(index == web.DESKTOP || item.index? "": "."+index), _hash: can.core.Keys(item._hash, index)}, target, function() {
// can.onappend.plugin(can._root.Action, {space: item.space, index: index, height: can.ConfHeight(), width: can.ConfWidth()-can.ui.project.offsetWidth}, function() {}, can.ui.content)
can.onappend.plugin(can._root.Action, {space: item.space, index: index, args: index == cli.XTERM? ["sh"]: [],
height: can.ConfHeight(), width: can.ConfWidth()-can.ui.project.offsetWidth, style: can.base.isIn(index, cli.XTERM, web.DESKTOP)? html.OUTPUT: "",
title: index == web.DESKTOP? item.name: "",
}, function(sub) {
sub.run = function(event, cmds, cb) { var msg = can.request(event); delete(msg.pod)
can.runAction(event, item.action, [item.cloud_uid, item.uid, index].concat(cmds), cb)
}
can._plugins = (can._plugins||[]).concat(sub)
}, can.ui.content)
})
},
layout: function(can) {
can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) {
can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, height, width) })
})
},
})

83
src/operation/template.go Normal file
View File

@ -0,0 +1,83 @@
package operation
import (
"shylinux.com/x/ice"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/operation/src/operation/model"
)
type template struct {
Table
order string `data:"2"`
fields string `data:"name,info,title,icons,repos,binary,template_status"`
create string `name:"create name* info title icons repos* binary*"`
modify string `name:"modify name* info title icons repos* binary*" style:"danger"`
install string `name:"install name* gateway_uid*" style:"notice" role:"worker"`
}
func (s template) Create(m *ice.Message, arg ...string) {
s.Insert(m, arg...)
}
func (s template) List(m *ice.Message, arg ...string) {
if m.IsTech() {
if len(arg) < 2 {
s.Select(m)
} else {
s.SelectDetail(m, model.UID, arg[1])
}
m.Table(func(value ice.Maps) {
if TemplateStatus(kit.Int(value[model.TEMPLATE_STATUS])) == TemplateOffline {
m.PushButton(s.Online, s.Modify)
} else {
m.PushButton(s.Install, s.Offline, s.Modify)
}
})
if m.Length() == 0 {
s.Button(m, "")
}
} else {
if len(arg) < 2 {
s.Select(m, model.STATUS, kit.Format(TemplateOnline))
} else {
s.SelectDetail(m, model.UID, arg[1])
}
if m.PushAction(s.Install).Action(); m.Length() == 0 {
m.Echo("请等待「平台管理员」创建模板")
}
}
m.Display("")
}
func (s template) Install(m *ice.Message, arg ...string) {
msg := m.Cmd(Gateway{}, m.Option(model.CLOUD_UID), m.Option(model.GATEWAY_UID))
m.Option(model.SPACE, kit.Keys(msg.Append(model.CLUSTER_SPACE), msg.Append(model.SPACE)))
m.Cmdy(project{}, s.Create, m.OptionSimple("name,icons,repos,binary"))
}
func (s template) Offline(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(TemplateOffline)})
s.RecordEventWithName(m, "")
}
func (s template) Online(m *ice.Message, arg ...string) {
s.Update(m, []string{model.STATUS, kit.Format(TemplateOnline)})
s.RecordEventWithName(m, "")
}
func (s template) Modify(m *ice.Message, arg ...string) {
s.Update(m, arg)
s.RecordEventWithName(m, "")
}
func init() { ice.TeamCtxCmd(template{}) }
type TemplateStatus int
const (
TemplateOffline TemplateStatus = iota
TemplateOnline
)
var TemplateStatusList = map[TemplateStatus]string{
TemplateOffline: "offline",
TemplateOnline: "online",
}
func (s TemplateStatus) String() string { return TemplateStatusList[s] }

View File

@ -0,0 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title||value.name, can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value)]},
{view: html.OUTPUT, list: [value.info||value.binary||value.repos]},
] })
},
})

View File

@ -1,6 +1,6 @@
package main
import (
_ "shylinux.com/x/community/src/renzhengshouquan"
_ "shylinux.com/x/mysql-story/src/db/mysql"
_ "shylinux.com/x/ice/devops"
_ "shylinux.com/x/ice/portal"
)

View File

@ -9,42 +9,32 @@ import (
type Case struct {
Table
order string `data:"3"`
fields string `data:"title,content,case_status,process_time,finish_time,plan_uid,user_uid"`
create string `name:"create title* content*" role:"leader,worker"`
modify string `name:"modify title* content*" role:"leader,worker"`
remove string `name:"remove" role:"leader,worker"`
process string `name:"process" role:"leader,worker"`
finish string `name:"finish" role:"leader,worker"`
planBind string `name:"planBind plan_uid*" role:"leader"`
order string `data:"5"`
fields string `data:"title,content,case_status,begin_time,end_time,process_time,finish_time,task_uid,plan_uid,user_uid"`
create string `name:"create task_uid* title* content* begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* begin_time*:select@date end_time*:select@date" role:"worker"`
}
func (s Case) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, arg...)
s.ValueCreate(m, kit.ArgDef(arg, kit.Simple(model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("72h"))...)...)
s.taskCount(m, "1")
s.planCount(m, "1")
s.GetCommandUID(m)
s.SendMessage(m, "", "")
s.SendMessage(s.GetCommandUID(m), "", "")
}
func (s Case) Remove(m *ice.Message, arg ...string) {
s.ValueRemove(m, arg...)
s.taskCount(m, "-1")
s.planCount(m, "-1")
}
func (s Case) List(m *ice.Message, arg ...string) {
isLeader, user_uid := s.IsLeader(m), m.Option(model.USER_UID)
user_uid := m.Option(model.USER_UID)
s.ValueList(m, arg).Table(func(value ice.Maps) {
button := []ice.Any{}
switch CaseStatus(kit.Int(value[model.CASE_STATUS])) {
case CaseCreate:
if isLeader && value[model.PLAN_UID] == "" {
button = append(button, s.PlanBind)
}
if isLeader || user_uid == value[model.USER_UID] {
if user_uid == value[model.USER_UID] {
button = append(button, s.Process)
}
case CaseProcess:
if isLeader || user_uid == value[model.USER_UID] {
if user_uid == value[model.USER_UID] {
button = append(button, s.Finish)
}
case CaseFinish:
@ -60,24 +50,17 @@ func (s Case) Process(m *ice.Message, arg ...string) {
func (s Case) Finish(m *ice.Message, arg ...string) {
s.changeStatus(m, CaseProcess, CaseFinish)
}
func (s Case) PlanBind(m *ice.Message, arg ...string) {
s.ValueModify(m, arg...)
s.planCount(m, "1")
}
func init() { ice.TeamCtxCmd(Case{}) }
func (s Case) changeStatus(m *ice.Message, from, to CaseStatus) {
s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time())
}
func (s Case) planCount(m *ice.Message, value string) {
s.Table.planCount(m, model.CASE_COUNT, value)
}
func (s Case) taskCount(m *ice.Message, value string) {
if m.IsErr() || m.Option(model.TASK_UID) == "" {
return
}
m.Cmd(task{}, s.AddCount, model.CASE_COUNT, value, m.Option(model.TASK_UID))
m.Cmd(Task{}, s.AddCount, model.CASE_COUNT, value, m.Option(model.TASK_UID))
}
type CaseStatus int

View File

@ -1,10 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title, can.onimport.textView(can, value), can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.STATUS, list: [can.base.TimeTrim(value.process_time), "~", can.base.TimeTrim(value.finish_time), "计划:", value.plan_title]},
{view: html.OUTPUT, list: [value.content]},
{view: html.TITLE, list: [value.title, can.onimport.textView(can, value)]},
{view: html.STATUS, list: [(value.process_time||value.begin_time).split(" ")[0], "计划:", value.plan_title]},
{view: html.OUTPUT, list: [value.content]}, can.onimport.titleAction(can, value),
] })
},
})

BIN
src/production/case.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -10,7 +10,10 @@ import (
type Table struct {
operation.Table
list string `name:"list story_uid uid auto" role:"void"`
remove string `name:"remove" role:"worker"`
process string `name:"process" role:"worker"`
finish string `name:"finish" role:"worker"`
list string `name:"list story_uid uid auto" role:"void"`
}
func (s Table) Inputs(m *ice.Message, arg ...string) {
@ -20,9 +23,11 @@ func (s Table) Inputs(m *ice.Message, arg ...string) {
case model.STORY_TYPE:
s.InputsList(m, StoryTypeList, arg...)
case model.PLAN_UID:
s.Fields(m, model.UID, model.TITLE)
m.Cmdy(plan{}, s.Select, m.OptionSimple(model.STORY_UID)).RenameAppend(model.UID, arg[0])
m.DisplayInputKeyNameIconTitle()
s.InputsUID(m, Plan{}, arg...)
case model.ISSUE_UID:
s.InputsUID(m, Issue{}, arg...)
case model.TASK_UID:
s.InputsUID(m, Task{}, arg...)
case model.ISSUE_TYPE:
s.InputsList(m, IssueTypeList, arg...)
case model.LEVEL:
@ -44,6 +49,8 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message {
value = IssueType(kit.Int(value)).String()
case model.ISSUE_STATUS:
value = IssueStatus(kit.Int(value)).String()
case model.DESIGN_STATUS:
value = DesignStatus(kit.Int(value)).String()
case model.TASK_STATUS:
value = TaskStatus(kit.Int(value)).String()
case model.CASE_STATUS:
@ -56,18 +63,12 @@ func (s Table) RewriteAppend(m *ice.Message, arg ...string) *ice.Message {
return s.Table.RewriteAppend(m)
}
func (s Table) SelectJoinPlan(m *ice.Message, arg ...string) {
s.SelectJoin(m, plan{}, model.TITLE)
s.SelectJoin(m, Plan{}, model.TITLE)
}
func (s Table) ChangeStatus(m *ice.Message, from, to int, arg ...string) {
s.Table.ChangeStatus(m, m.Option(model.STORY_UID), m.Option(model.UID), from, to, arg...)
s.DashboardUpdate(m)
}
func (s Table) planCount(m *ice.Message, key, value string) {
if m.IsErr() || m.Option(model.PLAN_UID) == "" {
return
}
m.Cmd(plan{}, s.AddCount, key, value, m.Option(model.PLAN_UID))
}
type Tables struct{ Table }

81
src/production/design.go Normal file
View File

@ -0,0 +1,81 @@
package production
import (
"shylinux.com/x/ice"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/operation/src/production/model"
)
type Design struct {
Table
order string `data:"3"`
fields string `data:"title,content,design_status,begin_time,end_time,process_time,finish_time,issue_uid,plan_uid,user_uid"`
create string `name:"create issue_uid* title* content* begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* begin_time*:select@date end_time*:select@date" role:"worker"`
}
func (s Design) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, kit.ArgDef(arg, kit.Simple(model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("72h"))...)...)
s.issueCount(m, "1")
s.SendMessage(s.GetCommandUID(m), "", "")
}
func (s Design) Remove(m *ice.Message, arg ...string) {
s.ValueRemove(m, arg...)
s.issueCount(m, "-1")
}
func (s Design) List(m *ice.Message, arg ...string) {
user_uid := m.Option(model.USER_UID)
s.ValueList(m, arg).Table(func(value ice.Maps) {
button := []ice.Any{}
switch DesignStatus(kit.Int(value[model.DESIGN_STATUS])) {
case DesignCreate:
if user_uid == value[model.USER_UID] {
button = append(button, s.Process)
}
case DesignProcess:
if user_uid == value[model.USER_UID] {
button = append(button, s.Finish)
}
case DesignFinish:
kit.If(len(arg) == 2, func() { s.DoneMessage(m) })
}
m.PushButton(button...)
}).Display("")
s.SelectJoinPlan(m)
}
func (s Design) Process(m *ice.Message, arg ...string) {
s.changeStatus(m, DesignCreate, DesignProcess)
}
func (s Design) Finish(m *ice.Message, arg ...string) {
s.changeStatus(m, DesignProcess, DesignFinish)
}
func init() { ice.TeamCtxCmd(Design{}) }
func (s Design) changeStatus(m *ice.Message, from, to DesignStatus) {
s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time())
}
func (s Design) issueCount(m *ice.Message, value string) Design {
if m.IsErr() || m.Option(model.ISSUE_UID) == "" {
return s
}
m.Cmd(Issue{}, s.AddCount, model.DESIGN_COUNT, value, m.Option(model.ISSUE_UID))
return s
}
type DesignStatus int
const (
DesignCreate DesignStatus = iota
DesignProcess
DesignFinish
)
var DesignStatusList = map[DesignStatus]string{
DesignCreate: "create",
DesignProcess: "process",
DesignFinish: "finish",
}
func (s DesignStatus) String() string { return DesignStatusList[s] }

9
src/production/design.js Normal file
View File

@ -0,0 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title, can.onimport.textView(can, value)]},
{view: html.STATUS, list: [can.onimport.beginTime(can, value), "计划:", value.plan_title]},
{view: html.OUTPUT, list: [value.content]}, can.onimport.titleAction(can, value),
] })
},
})

BIN
src/production/design.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -7,36 +7,35 @@ import (
"shylinux.com/x/operation/src/production/model"
)
type issue struct {
type Issue struct {
Table
task task
order string `data:"2"`
fields string `data:"title,content,issue_type,level,issue_status,task_count,process_time,finish_time,plan_uid,user_uid"`
create string `name:"create title* content* issue_type:select level:select" role:"leader,worker"`
modify string `name:"modify title* content* issue_type*:select level*:select" role:"leader,worker"`
remove string `name:"remove" role:"leader,worker"`
reject string `name:"reject" role:"leader"`
approve string `name:"approve" role:"leader"`
process string `name:"process" role:"leader,worker"`
finish string `name:"finish" role:"leader,worker"`
planBind string `name:"planBind plan_uid*" role:"leader"`
taskCreate string `name:"taskCreate title* content* begin_time:select@date end_time:select@date" role:"leader,worker"`
order string `data:"2"`
fields string `data:"title,content,level,issue_type,issue_status,price,link,design_count,task_count,begin_time,end_time,process_time,finish_time,plan_uid,user_uid"`
create string `name:"create plan_uid* title* content* issue_type:select level:select price begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* issue_type*:select level*:select price begin_time:select@date end_time:select@date" role:"worker"`
reject string `name:"reject" role:"leader"`
approve string `name:"approve" role:"leader"`
submit string `name:"submit" role:"worker"`
reback string `name:"reback" role:"leader"`
payfor string `name:"payfor" role:"worker"`
designCreate string `name:"designCreate title* content* begin_time:select@date end_time:select@date" role:"worker"`
taskCreate string `name:"taskCreate title* content* begin_time:select@date end_time:select@date" role:"worker"`
}
func (s issue) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, kit.ArgDef(arg, kit.Simple(model.ISSUE_TYPE, IssueFeature, model.LEVEL, Level3)...)...)
s.planCount(m, "1")
s.DashboardUpdate(m)
s.GetCommandUID(m)
s.SendMessage(m, "", "")
func (s Issue) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, kit.ArgDef(s.TransPrice(m, arg), kit.Simple(
model.ISSUE_TYPE, IssueFeature, model.LEVEL, Level3, model.PRICE, "1000",
model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("72h"),
)...)...)
s.planCount(m, "1").DashboardUpdate(m)
s.SendMessage(s.GetCommandUID(m), "", "")
}
func (s issue) Remove(m *ice.Message, arg ...string) {
func (s Issue) Remove(m *ice.Message, arg ...string) {
s.ValueRemove(m, arg...)
s.planCount(m, "-1")
s.DashboardUpdate(m)
s.planCount(m, "-1").DashboardUpdate(m)
}
func (s issue) List(m *ice.Message, arg ...string) {
isLeader, user_uid := s.IsLeader(m), m.Option(model.USER_UID)
func (s Issue) List(m *ice.Message, arg ...string) {
isLeader, isWorker, user_uid := s.IsLeader(m), s.IsWorker(m), m.Option(model.USER_UID)
s.ValueList(m, arg).Table(func(value ice.Maps) {
button := []ice.Any{}
switch IssueStatus(kit.Int(value[model.ISSUE_STATUS])) {
@ -44,57 +43,81 @@ func (s issue) List(m *ice.Message, arg ...string) {
if isLeader {
button = append(button, s.Reject, s.Approve)
}
case IssueApproved:
if isLeader && value[model.PLAN_UID] == "" {
button = append(button, s.PlanBind)
if user_uid == value[model.USER_UID] {
button = append(button, s.Modify, s.Remove)
}
if isLeader || user_uid == value[model.USER_UID] {
case IssueApproved:
if user_uid == value[model.USER_UID] {
button = append(button, s.Process)
}
case IssueProcess:
button = append(button, s.TaskCreate)
if isLeader || user_uid == value[model.USER_UID] {
button = append(button, s.Finish)
if user_uid == value[model.USER_UID] {
button = append(button, s.Submit)
}
if isLeader && kit.Int(value[model.PRICE]) > 0 {
// button = append(button, s.Payfor)
}
case IssueSubmit:
if isLeader {
button = append(button, s.Reback, s.Finish)
}
case IssueFinish:
kit.If(len(arg) == 2, func() { s.DoneMessage(m) })
if isWorker {
button = append(button, s.DesignCreate, s.TaskCreate)
}
if isLeader && kit.Int(value[model.PRICE]) > 0 {
// button = append(button, s.Payfor)
}
kit.If(len(arg) == 2 && value[model.PRICE] == "0", func() { s.DoneMessage(m) })
}
m.PushButton(button...)
}).Display("")
s.SelectJoinPlan(m)
}
func (s issue) Reject(m *ice.Message, arg ...string) {
func (s Issue) Reject(m *ice.Message, arg ...string) {
s.changeStatus(m, IssueCreate, IssueRejected)
}
func (s issue) Approve(m *ice.Message, arg ...string) {
func (s Issue) Approve(m *ice.Message, arg ...string) {
s.changeStatus(m, IssueCreate, IssueApproved)
}
func (s issue) Process(m *ice.Message, arg ...string) {
func (s Issue) Process(m *ice.Message, arg ...string) {
s.changeStatus(m, IssueApproved, IssueProcess)
}
func (s issue) Finish(m *ice.Message, arg ...string) {
count := m.Cmd(s.task, s.Select, "issue_uid = ? AND status != ?", m.Option(model.UID), TaskFinish).Length()
func (s Issue) Submit(m *ice.Message, arg ...string) {
s.ChangeStatus(m, int(IssueProcess), int(IssueSubmit))
}
func (s Issue) Reback(m *ice.Message, arg ...string) {
s.ChangeStatus(m, int(IssueSubmit), int(IssueProcess))
}
func (s Issue) Finish(m *ice.Message, arg ...string) {
count := m.Cmd(Design{}, s.Select, "issue_uid = ? AND status != ?", m.Option(model.UID), DesignFinish).Length()
if m.WarnNotValid(count > 0, kit.Format("还有 %v 个未完成的设计", count)) {
return
}
count = m.Cmd(Task{}, s.Select, "issue_uid = ? AND status != ?", m.Option(model.UID), TaskFinish).Length()
if m.WarnNotValid(count > 0, kit.Format("还有 %v 个未完成的任务", count)) {
return
}
s.changeStatus(m, IssueProcess, IssueFinish)
s.DashboardUpdate(m)
s.changeStatus(m, IssueSubmit, IssueFinish)
}
func (s issue) PlanBind(m *ice.Message, arg ...string) {
s.ValueModify(m, arg...)
s.planCount(m, "1")
func (s Issue) DesignCreate(m *ice.Message, arg ...string) {
s.OtherCreate(m, Design{}, model.ISSUE_UID, m.Option(model.UID), arg, m.OptionSimple(model.PLAN_UID))
}
func (s issue) TaskCreate(m *ice.Message, arg ...string) {
m.Cmd(s.task, s.Create, arg, model.ISSUE_UID, m.Option(model.UID), m.OptionSimple(model.PLAN_UID))
func (s Issue) TaskCreate(m *ice.Message, arg ...string) {
s.OtherCreate(m, Task{}, model.ISSUE_UID, m.Option(model.UID), arg, m.OptionSimple(model.PLAN_UID))
}
func init() { ice.TeamCtxCmd(issue{}) }
func init() { ice.TeamCtxCmd(Issue{}) }
func (s issue) changeStatus(m *ice.Message, from, to IssueStatus) {
func (s Issue) changeStatus(m *ice.Message, from, to IssueStatus) {
s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time())
}
func (s issue) planCount(m *ice.Message, value string) {
s.Table.planCount(m, model.ISSUE_COUNT, value)
func (s Issue) planCount(m *ice.Message, value string) Issue {
if m.IsErr() || m.Option(model.PLAN_UID) == "" {
return s
}
m.Cmd(Plan{}, s.AddCount, model.ISSUE_COUNT, value, m.Option(model.PLAN_UID))
return s
}
type IssueType int
@ -118,6 +141,8 @@ const (
IssueRejected
IssueApproved
IssueProcess
IssueSubmit
IssueReback
IssueFinish
)
@ -126,6 +151,8 @@ var IssueStatusList = map[IssueStatus]string{
IssueRejected: "rejected",
IssueApproved: "approved",
IssueProcess: "process",
IssueSubmit: "submit",
IssueReback: "reback",
IssueFinish: "finish",
}

View File

@ -4,14 +4,16 @@ Volcanos(chat.ONIMPORT, {
{view: html.TITLE, list: [value.title,
value.issue_type != "feature" && can.onimport.textView(can, value, "issue_type"),
value.level != "level-3" && can.onimport.textView(can, value, "level"),
can.onimport.textView(can, value), can.onimport.titleAction(can, value),
can.onimport.textView(can, value),
]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.STATUS, list: [
can.base.TimeTrim(value.process_time), "~", can.base.TimeTrim(value.finish_time),
"计划:", value.plan_title, "任务:", value.task_count+" 个",
can.onimport.beginTime(can, value),
"设计:", value.design_count+" 个",
"任务:", value.task_count+" 个",
"计划:", value.plan_title,
]},
{view: html.OUTPUT, list: [value.content]},
value.price > 0 && {view: html.OUTPUT, list: ["报价: "+value.price+" 元"]},
{view: html.OUTPUT, list: [value.content]}, can.onimport.titleAction(can, value),
] })
},
})

BIN
src/production/issue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -9,8 +9,11 @@ const (
TYPE = "type"
LEVEL = "level"
STATUS = "status"
PRICE = "price"
LINK = "link"
TITLE = "title"
CONTENT = "content"
VERSION = "version"
USER_UID = "user_uid"
USER_ROLE = "user_role"
USER_STORY_ROLE = "user_story_role"
@ -19,6 +22,8 @@ const (
STORY_TYPE = "story_type"
PLAN_UID = "plan_uid"
PLAN_STATUS = "plan_status"
DESIGN_STATUS = "design_status"
DESIGN_COUNT = "design_count"
ISSUE_COUNT = "issue_count"
TASK_COUNT = "task_count"
CASE_COUNT = "case_count"
@ -44,10 +49,9 @@ type Story struct {
type Plan struct {
db.ModelContent
StoryUID string `gorm:"type:char(32);index"`
Version string `gorm:"type:varchar(16)"`
Status uint8 `gorm:"default:0"`
IssueCount int `gorm:"default:0"`
TaskCount int `gorm:"default:0"`
CaseCount int `gorm:"default:0"`
BeginTime db.Time
EndTime db.Time
ProcessTime db.Time
@ -55,23 +59,26 @@ type Plan struct {
}
type Issue struct {
Common
DesignCount int `gorm:"default:0"`
TaskCount int `gorm:"default:0"`
RejectTime db.Time
ApproveTime db.Time
}
type Design struct {
Common
IssueUID string `gorm:"type:char(32);index"`
}
type Task struct {
Common
IssueUID string `gorm:"type:char(32);index"`
CaseCount int `gorm:"default:0"`
BeginTime db.Time
EndTime db.Time
}
type Case struct {
Common
TaskUID string `gorm:"type:char(32);index"`
}
func init() { db.CmdModels("", &UserStory{}, &Story{}, &Plan{}, &Issue{}, &Task{}, &Case{}) }
func init() { db.CmdModels("", &UserStory{}, &Story{}, &Plan{}, &Issue{}, &Design{}, &Task{}, &Case{}) }
type Common struct {
db.ModelContent
@ -80,6 +87,11 @@ type Common struct {
Type uint8 `gorm:"default:0"`
Level uint8 `gorm:"default:2"`
Status uint8 `gorm:"default:0"`
Price int `gorm:"default:0"`
Score int `gorm:"default:0"`
Link string `gorm:"type:varchar(255)"`
BeginTime db.Time
EndTime db.Time
ProcessTime db.Time
FinishTime db.Time
}

1
src/production/plan.css Normal file
View File

@ -0,0 +1 @@
$output div.item.card>div.output span.status.create { color:var(--danger-bg-color); }

View File

@ -7,25 +7,25 @@ import (
"shylinux.com/x/operation/src/production/model"
)
type plan struct {
type Plan struct {
Table
issue issue
order string `data:"1"`
fields string `data:"title,content,plan_status,issue_count,task_count,case_count,begin_time,end_time,process_time,finish_time,user_uid"`
create string `name:"create title* content* begin_time:select@date end_time:select@date" role:"leader"`
modify string `name:"modify title* content* begin_time*:select@date end_time*:select@date" role:"leader"`
fields string `data:"title,content,version,plan_status,issue_count,begin_time,end_time,process_time,finish_time,user_uid"`
create string `name:"create title* content version begin_time:select@date end_time:select@date" role:"leader"`
modify string `name:"modify title* content version begin_time*:select@date end_time*:select@date" role:"leader"`
remove string `name:"remove" role:"leader"`
process string `name:"process" role:"leader"`
finish string `name:"finish" role:"leader"`
issueCreate string `name:"issueCreate title* content* issue_type:select level:select" role:"leader,worker"`
issueCreate string `name:"issueCreate title* content* issue_type:select level:select price begin_time:select@date end_time:select@date" role:"worker"`
}
func (s plan) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, kit.ArgDef(arg, kit.Simple(model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("720h"))...)...)
func (s Plan) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, kit.ArgDef(arg, kit.Simple(model.VERSION, "v1.0", model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("168h"))...)...)
s.SendMessage(m, "", "")
}
func (s plan) List(m *ice.Message, arg ...string) {
isLeader := s.IsLeader(m)
func (s Plan) List(m *ice.Message, arg ...string) {
isLeader, isWorker := s.IsLeader(m), s.IsWorker(m)
defer kit.If(!isLeader, func() { m.SetResult().Action() })
s.ValueList(m, arg).Table(func(value ice.Maps) {
button := []ice.Any{}
switch PlanStatus(kit.Int(value[model.PLAN_STATUS])) {
@ -34,7 +34,9 @@ func (s plan) List(m *ice.Message, arg ...string) {
button = append(button, s.Process, s.Modify, s.Remove)
}
case PlanProcess:
button = append(button, s.IssueCreate)
if isWorker {
button = append(button, s.IssueCreate)
}
if isLeader {
button = append(button, s.Finish)
}
@ -45,26 +47,28 @@ func (s plan) List(m *ice.Message, arg ...string) {
kit.If(len(arg) == 2, func() { s.DoneMessage(m) })
}
m.PushButton(button...)
}).Display("")
kit.If(!isLeader, func() { m.Action() })
}).Display("").DisplayCSS("").Sort("plan_status,issue_count,create_time")
}
func (s plan) Process(m *ice.Message, arg ...string) {
func (s Plan) Process(m *ice.Message, arg ...string) {
s.changeStatus(m, PlanCreate, PlanProcess)
}
func (s plan) Finish(m *ice.Message, arg ...string) {
count := m.Cmd(s.issue, s.Select, "plan_uid = ? AND status != ?", m.Option(model.UID), IssueFinish).Length()
if m.WarnNotValid(count > 0, kit.Format("还有 %v 个未完成的需求", count)) {
return
func (s Plan) Finish(m *ice.Message, arg ...string) {
count := m.Cmd(Issue{}, s.Select, "plan_uid = ? AND status != ?", m.Option(model.UID), IssueFinish).Length()
if !m.WarnNotValid(count > 0, kit.Format("还有 %v 个未完成的需求", count)) {
s.changeStatus(m, PlanProcess, PlanFinish)
}
s.changeStatus(m, PlanProcess, PlanFinish)
}
func (s plan) IssueCreate(m *ice.Message, arg ...string) {
m.Cmd(s.issue, s.Create, arg, model.PLAN_UID, m.Option(model.UID))
func (s Plan) IssueCreate(m *ice.Message, arg ...string) {
s.OtherCreate(m, Issue{}, model.PLAN_UID, m.Option(model.UID), arg)
}
func (s Table) OtherCreate(m *ice.Message, target ice.Any, arg ...ice.Any) {
m.Cmdy(target, s.Create, kit.Simple(arg...))
kit.If(!m.IsErr(), func() { m.ProcessField(target, []string{m.Option(model.STORY_UID), m.Result()}) })
}
func init() { ice.TeamCtxCmd(plan{}) }
func init() { ice.TeamCtxCmd(Plan{}) }
func (s plan) changeStatus(m *ice.Message, from, to PlanStatus) {
func (s Plan) changeStatus(m *ice.Message, from, to PlanStatus) {
s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time())
}

View File

@ -1,14 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title, can.onimport.textView(can, value), can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.STATUS, list: [value.begin_time.split(" ")[0], "~", value.end_time.split(" ")[0]]},
{view: html.STATUS, list: [
can.base.TimeTrim(value.process_time), "~", can.base.TimeTrim(value.finish_time),
"需求:", value.issue_count+" 个", "任务:", value.task_count+" 个", "用例:", value.case_count+" 个",
]},
{view: html.OUTPUT, list: [value.content]},
{view: html.TITLE, list: [value.title, value.version, can.onimport.textView(can, value)]},
{view: html.STATUS, list: [can.onimport.beginTime(can, value), "需求量:", value.issue_count+" 个"]},
{view: html.OUTPUT, list: [value.content]}, can.onimport.titleAction(can, value),
] })
},
})

BIN
src/production/plan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -15,10 +15,10 @@ type Portal struct {
func (s Portal) AfterPlaceAuth(m *ice.Message, arg ...string) {
defer s.DashboardCreate(m, "")()
s.DashboardInsert(m, 1, "需求总量", "个", issue{}, "")
s.DashboardInsert(m, 2, "需求待办", "个", issue{}, "", "story_uid = ? AND status != ? AND status != ?", m.Option(model.STORY_UID), IssueRejected, IssueFinish)
s.DashboardInsert(m, 3, "任务总量", "个", task{}, "")
s.DashboardInsert(m, 4, "任务待办", "个", task{}, "", "story_uid = ? AND status != ?", m.Option(model.STORY_UID), TaskFinish)
s.DashboardInsert(m, 1, "需求总量", "个", Issue{}, "")
s.DashboardInsert(m, 2, "需求待办", "个", Issue{}, "", "story_uid = ? AND status != ? AND status != ?", m.Option(model.STORY_UID), IssueRejected, IssueFinish)
s.DashboardInsert(m, 4, "任务待办", "个", Task{}, "", "story_uid = ? AND status != ?", m.Option(model.STORY_UID), TaskFinish)
s.DashboardInsert(m, 3, "任务总量", "个", Task{}, "")
}
func init() { gonganxitong.PortalCmd(Portal{Portal: guanlixitong.NewPortal(userStory{}, story{})}) }

5
src/production/portal.js Normal file
View File

@ -0,0 +1,5 @@
Volcanos(chat.ONIMPORT, {
beginTime: function(can, value) {
return (value.process_time||value.begin_time).split(" ")[0]+" ~ "+(value.finish_time||value.end_time).split(" ")[0]
},
})

View File

@ -1,37 +1,47 @@
{
"portal": "产品迭代", "member": "项目成员",
"plan": "迭代计划", "issue": "产品需求", "task": "开发任务", "case": "测试用例",
"planBind": "绑定计划", "process": "开始",
"issueCreate": "创建需求", "taskCreate": "创建任务", "caseCreate": "创建用例",
"plan": "迭代计划", "issue": "产品需求", "design": "界面设计", "task": "开发任务", "case": "测试用例",
"process": "开始", "submit": "提交", "reback": "返工", "finish": "完成", "payfor": "支付",
"issueCreate": "创建需求", "designCreate": "创建设计", "taskCreate": "创建任务", "caseCreate": "创建用例",
"style": {
"process": "notice",
"finish": "danger",
"submit": "notice",
"reback": "notice",
"finish": "notice",
"payfor": "notice",
"issueCreate": "notice",
"designCreate": "notice",
"taskCreate": "notice",
"caseCreate": "notice"
},
"icons": {
"plan": "https://img.icons8.com/officel/80/timeline-week.png",
"issue": "https://img.icons8.com/officel/80/communication.png",
"task": "https://img.icons8.com/officel/80/tasks.png",
"case": "https://img.icons8.com/officel/80/faq.png"
"plan": "plan.png",
"issue": "issue.png",
"design": "design.png",
"task": "task.png",
"case": "case.png"
},
"input": {
"My Story": "我的产品",
"user_story_role": "用户角色",
"story_name": "产品名称",
"story_type": "产品类型",
"plan_uid": "产品计划",
"plan_title": "产品计划",
"plan_status": "计划状态",
"story_name": "产品名称",
"story_type": "产品类型",
"issue_uid": "产品需求",
"issue_type": "需求类型",
"issue_status": "需求状态",
"issue_count": "需求数量",
"design_status": "设计状态",
"design_count": "设计数量",
"task_uid": "开发任务",
"task_status": "任务状态",
"task_count": "任务数量",
"case_status": "用例状态",
"case_count": "用例数量",
"issue_count": "需求数量",
"task_count": "任务数量",
"process_time": "开始时间",
"finish_time": "完成时间",
"level": "优先级"
},
"value": {
@ -47,7 +57,7 @@
}
},
"story_type": {
"custom": "应用软件",
"application": "应用软件",
"enterprise": "企业软件",
"industry": "工业软件",
"military": "军用软件",
@ -68,13 +78,23 @@
"issue_status": {
"create": "待评审",
"rejected": "已驳回",
"approved": "待开发",
"process": "开发中",
"approved": "待调研",
"process": "调研中",
"submit": "已提交",
"finish": "已完成",
"style": {
"create": "danger",
"approved": "danger",
"rejected": "danger"
"rejected": "danger",
"submit": "danger"
}
},
"design_status": {
"create": "待设计",
"process": "设计中",
"finish": "已完成",
"style": {
"create": "danger"
}
},
"task_status": {

View File

@ -9,7 +9,7 @@ func init() { ice.TeamCtxCmd(story{}) }
type StoryType int
const (
StoryCustom StoryType = iota
StoryApplication StoryType = iota
StoryEnterprise
StoryIndustry
StoryMilitary
@ -17,11 +17,11 @@ const (
)
var StoryTypeList = map[StoryType]string{
StoryCustom: "custom",
StoryEnterprise: "enterprise",
StoryIndustry: "industry",
StoryMilitary: "military",
StorySystem: "system",
StoryApplication: "application",
StoryEnterprise: "enterprise",
StoryIndustry: "industry",
StoryMilitary: "military",
StorySystem: "system",
}
func (s StoryType) String() string { return StoryTypeList[s] }

View File

@ -7,49 +7,38 @@ import (
"shylinux.com/x/operation/src/production/model"
)
type task struct {
type Task struct {
Table
Case Case
order string `data:"3"`
order string `data:"4"`
fields string `data:"title,content,task_status,case_count,begin_time,end_time,process_time,finish_time,issue_uid,plan_uid,user_uid"`
create string `name:"create title* content* begin_time:select@date end_time:select@date" role:"leader,worker"`
modify string `name:"modify title* content* begin_time*:select@date end_time*:select@date" role:"leader,worker"`
remove string `name:"remove" role:"leader,worker"`
process string `name:"process" role:"leader,worker"`
finish string `name:"finish" role:"leader,worker"`
planBind string `name:"planBind plan_uid*" role:"leader"`
caseCreate string `name:"caseCreate title* content*" role:"leader,worker"`
create string `name:"create issue_uid* title* content* begin_time:select@date end_time:select@date" role:"worker"`
modify string `name:"modify title* content* begin_time*:select@date end_time*:select@date" role:"worker"`
caseCreate string `name:"caseCreate title* content* begin_time:select@date end_time:select@date" role:"worker"`
}
func (s task) Create(m *ice.Message, arg ...string) {
func (s Task) Create(m *ice.Message, arg ...string) {
s.ValueCreate(m, kit.ArgDef(arg, kit.Simple(model.BEGIN_TIME, m.Time(), model.END_TIME, m.Time("72h"))...)...)
s.issueCount(m, "1")
s.planCount(m, "1")
s.DashboardUpdate(m)
s.GetCommandUID(m)
s.SendMessage(m, "", "")
s.issueCount(m, "1").DashboardUpdate(m)
s.SendMessage(s.GetCommandUID(m), "", "")
}
func (s task) Remove(m *ice.Message, arg ...string) {
func (s Task) Remove(m *ice.Message, arg ...string) {
s.ValueRemove(m, arg...)
s.issueCount(m, "-1")
s.planCount(m, "-1")
s.DashboardUpdate(m)
s.issueCount(m, "-1").DashboardUpdate(m)
}
func (s task) List(m *ice.Message, arg ...string) {
isLeader, user_uid := s.IsLeader(m), m.Option(model.USER_UID)
func (s Task) List(m *ice.Message, arg ...string) {
isWorker, user_uid := s.IsWorker(m), m.Option(model.USER_UID)
s.ValueList(m, arg).Table(func(value ice.Maps) {
button := []ice.Any{}
switch TaskStatus(kit.Int(value[model.TASK_STATUS])) {
case TaskCreate:
if isLeader && value[model.PLAN_UID] == "" {
button = append(button, s.PlanBind)
}
if isLeader || user_uid == value[model.USER_UID] {
if user_uid == value[model.USER_UID] {
button = append(button, s.Process)
}
case TaskProcess:
button = append(button, s.CaseCreate)
if isLeader || user_uid == value[model.USER_UID] {
if isWorker {
button = append(button, s.CaseCreate)
}
if user_uid == value[model.USER_UID] {
button = append(button, s.Finish)
}
case TaskFinish:
@ -59,38 +48,32 @@ func (s task) List(m *ice.Message, arg ...string) {
}).Display("")
s.SelectJoinPlan(m)
}
func (s task) Process(m *ice.Message, arg ...string) {
func (s Task) Process(m *ice.Message, arg ...string) {
s.changeStatus(m, TaskCreate, TaskProcess)
}
func (s task) Finish(m *ice.Message, arg ...string) {
count := m.Cmd(s.Case, s.Select, "task_uid = ? AND status != ?", m.Option(model.UID), CaseFinish).Length()
func (s Task) Finish(m *ice.Message, arg ...string) {
count := m.Cmd(Case{}, s.Select, "task_uid = ? AND status != ?", m.Option(model.UID), CaseFinish).Length()
if m.WarnNotValid(count > 0, kit.Format("还有 %v 个未完成的用例", count)) {
return
}
s.changeStatus(m, TaskProcess, TaskFinish)
}
func (s Task) CaseCreate(m *ice.Message, arg ...string) {
s.OtherCreate(m, Case{}, model.TASK_UID, m.Option(model.UID), arg, m.OptionSimple(model.PLAN_UID))
}
func init() { ice.TeamCtxCmd(Task{}) }
func (s Task) changeStatus(m *ice.Message, from, to TaskStatus) {
s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time())
s.DashboardUpdate(m)
}
func (s task) PlanBind(m *ice.Message, arg ...string) {
s.ValueModify(m, arg...)
s.planCount(m, "1")
}
func (s task) CaseCreate(m *ice.Message, arg ...string) {
m.Cmd(s.Case, s.Create, arg, model.TASK_UID, m.Option(model.UID), m.OptionSimple(model.PLAN_UID))
}
func init() { ice.TeamCtxCmd(task{}) }
func (s task) changeStatus(m *ice.Message, from, to TaskStatus) {
s.ChangeStatus(m, int(from), int(to), m.ActionKey()+"_time", m.Time())
}
func (s task) planCount(m *ice.Message, value string) {
s.Table.planCount(m, model.TASK_COUNT, value)
}
func (s task) issueCount(m *ice.Message, value string) {
func (s Task) issueCount(m *ice.Message, value string) Task {
if m.IsErr() || m.Option(model.ISSUE_UID) == "" {
return
return s
}
m.Cmd(issue{}, s.AddCount, model.TASK_COUNT, value, m.Option(model.ISSUE_UID))
m.Cmd(Issue{}, s.AddCount, model.TASK_COUNT, value, m.Option(model.ISSUE_UID))
return s
}
type TaskStatus int

View File

@ -1,10 +1,9 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title, can.onimport.textView(can, value), can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.STATUS, list: [can.base.TimeTrim(value.process_time), "~", can.base.TimeTrim(value.finish_time), "计划:", value.plan_title, "用例:", value.case_count+" 个"]},
{view: html.OUTPUT, list: [value.content]},
{view: html.TITLE, list: [value.title, can.onimport.textView(can, value)]},
{view: html.STATUS, list: [can.onimport.beginTime(can, value), "用例:", value.case_count+" 个", "计划:", value.plan_title]},
{view: html.OUTPUT, list: [value.content]}, can.onimport.titleAction(can, value),
] })
},
})

BIN
src/production/task.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,16 +1,16 @@
package gonganxitong
package {{.Option "zone"}}
import "shylinux.com/x/ice"
type {{.Option "name"}} struct {
Table
Tables
fields string `data:"title,content"`
create string `name:"create title* content*" role:"leader"`
remove string `name:"remove" role:"leader"`
}
func (s {{.Option "name"}}) Create(m *ice.Message, arg ...string) { s.ValueCreate(m, arg...) }
func (s {{.Option "name"}}) Remove(m *ice.Message, arg ...string) { s.ValueRemove(m, arg...) }
func (s {{.Option "name"}}) List(m *ice.Message, arg ...string) { s.ValueList(m, arg).Display("") }
func (s {{.Option "name"}}) List(m *ice.Message, arg ...string) {
// s.ValueList(m, arg).Display("")
}
func init() { ice.TeamCtxCmd({{.Option "name"}}{}) }

View File

@ -1,7 +1,7 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.myView(can, msg, function(value) { return [
{view: html.TITLE, list: [value.title||value.name||value.user_name]},
{view: html.TITLE, list: [value.title||value.name||value.user_name, can.onimport.titleAction(can, value)]},
{view: html.STATUS, list: [value.uid.slice(0, 6), can.onimport.timeView(can, value), value.user_name]},
{view: html.OUTPUT, list: [value.content||value.info]},
] })

View File

@ -1,16 +1,34 @@
{
"047cb1827018c121a26a3dfe527fb629": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.dashboard.quotalist",
"time": "2025-04-19 08:28:36.340"
}
},
"0fdb75d726752dab583e67287a8b378e": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.dashboard.message",
"name": "消息待办",
"order": "902",
"time": "2024-09-03 10:34:55.194"
}
},
"1b65a1e29a6fbafcfc923377c17e0786": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.dashboard.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.910"
}
},
"2bda2c05c188eefba31832c7a12fe046": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.dashboard.qrcode",
"name": "场景码",
"order": "501",
@ -20,7 +38,7 @@
},
"2fd5ee121c2a76863adb7e5170d0411e": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.dashboard.member",
"name": "组织成员",
"order": "102",
@ -30,7 +48,7 @@
},
"33d8cc46706c23ba4b7f4b4ed7a9ceeb": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.dashboard.support",
"name": "客服支持",
"order": "905",
@ -39,7 +57,7 @@
},
"4b2bf7c9b86f0fa23d0c2f9722523651": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.dashboard.event",
"name": "事件流",
"order": "504",
@ -47,9 +65,20 @@
"time": "2024-09-03 10:34:55.202"
}
},
"540ddf077c3c36f74bff3cd7bfca960c": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.dashboard.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:01.339"
}
},
"61e32fdb1693caabfd9d9a116bdcefad": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.dashboard.setting",
"name": "服务配置",
"order": "103",
@ -57,18 +86,57 @@
"time": "2024-09-21 08:58:33.696"
}
},
"6bed6f6b60d01503a6060b8e3e7fae96": {
"meta": {
"icons": "https://img.icons8.com/officel/80/data-configuration.png",
"index": "web.team.dashboard.cleanup",
"name": "数据清理",
"order": "3",
"role": "leader",
"time": "2024-12-09 16:37:31.617"
}
},
"7c976e2b537da5ed93131b1f4a1833d8": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.dashboard.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.766"
}
},
"85e9ad5c568cceaa0aa273431f2cfcc2": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.dashboard.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.987"
}
},
"9b9207dcf4b99c9bd85f2dbb98cce04d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.dashboard.recent",
"name": "最近访问",
"order": "903",
"time": "2024-09-03 10:34:55.195"
}
},
"a14fa6b45b1627e58a3720453c829620": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.dashboard.spendlist",
"time": "2025-04-19 08:28:36.342"
}
},
"a9e4e21d0f48ba85879164aa94bb97e7": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.dashboard.service",
"name": "服务发现",
"order": "904",
@ -77,7 +145,7 @@
},
"c381566111b7fa54b6dc78b1764c0503": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.dashboard.allow",
"name": "权限审批",
"order": "503",
@ -93,7 +161,19 @@
"name": "连接配置",
"order": "1",
"role": "leader",
"time": "2024-09-18 10:11:37.406"
"time": "2024-09-18 10:11:37.406",
"type": "mysql"
}
},
"d13cf7ba94dbc15ff9fd04603a2ecfc8": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.dashboard.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.762"
}
},
"e2e828ce2e60c2d48b3d3eceb0cb33d3": {
@ -103,13 +183,24 @@
"init": "2",
"name": "数据汇总",
"order": "2",
"role": "leader,worker,server",
"role": "leader,worker",
"time": "2024-09-03 10:34:55.200"
}
},
"e3b889de9ace6b7f42008f8e0732effc": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.dashboard.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.977"
}
},
"e4039b1993b663907a2f2aa12a4fd104": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.dashboard.credit",
"name": "用户名片",
"order": "101",
@ -118,7 +209,7 @@
},
"e96c0373ddfbf817f5fd8970a6c69206": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.dashboard.notice",
"name": "通知公告",
"order": "505",
@ -128,7 +219,7 @@
},
"f12f682b6938fe6bdaafd58bc683882d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.dashboard.market",
"name": "人民广场",
"order": "901",
@ -137,7 +228,7 @@
},
"ffdabf002ce8700a7a1ecb2ddadfbf96": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.dashboard.apply",
"name": "权限申请",
"order": "502",

View File

@ -1,60 +0,0 @@
{
"535a365079a04575a3ebcc8335ee6e14": {
"meta": {
"index": "web.team.database.event",
"order": "93",
"role": "creator",
"time": "2024-09-03 10:27:06.386"
}
},
"719a6d97576235e241f0d6809a434ada": {
"meta": {
"index": "web.team.database.support",
"order": "103",
"time": "2024-09-03 10:27:06.390"
}
},
"b7894c3c001669f5ec1ac8f50c0d41de": {
"meta": {
"index": "web.team.database.recent",
"order": "101",
"time": "2024-09-03 10:27:06.385"
}
},
"c8e039a1aab9e850fe37cff5195ecdef": {
"meta": {
"index": "web.team.database.service",
"order": "102",
"time": "2024-09-03 10:27:06.384"
}
},
"da2601053bd94ff5d90afa3634b6f1ff": {
"meta": {
"index": "web.team.database.summary",
"time": "2024-09-03 10:27:06.382"
}
},
"dc5a31212f039dac07ae246b90a313aa": {
"meta": {
"index": "web.team.database.message",
"order": "100",
"time": "2024-09-03 10:27:06.381"
}
},
"e20005fb113060582cc3b37df321e859": {
"meta": {
"index": "web.team.database.allow",
"order": "92",
"role": "creator",
"time": "2024-09-03 10:27:06.388"
}
},
"f2f1ca7870c34140fe5625e45fb95ead": {
"meta": {
"index": "web.team.database.apply",
"order": "91",
"role": "creator",
"time": "2024-09-03 10:27:06.389"
}
}
}

View File

@ -1,7 +1,7 @@
{
"0bea40222e9b6e5925bebd060815779b": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.development.event",
"name": "事件流",
"order": "504",
@ -9,9 +9,20 @@
"time": "2024-09-03 10:22:15.300"
}
},
"149aeb9426d25387396b3f60ea618df7": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.development.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.762"
}
},
"2dde4851ba7e250e914790995d78f408": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.development.recent",
"name": "最近访问",
"order": "903",
@ -20,7 +31,7 @@
},
"3a84c93f797bf549e296841c33e78fae": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.development.credit",
"name": "用户名片",
"order": "101",
@ -29,7 +40,7 @@
},
"4fedc06280d241291c9e826e57532333": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.development.service",
"name": "服务发现",
"order": "904",
@ -47,7 +58,7 @@
},
"65bbf43dd9dd847f2c85f827030ea8ca": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.development.setting",
"name": "服务配置",
"order": "103",
@ -57,16 +68,38 @@
},
"6c38b2d75cf77d3f3be03d4755650660": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.development.support",
"name": "客服支持",
"order": "905",
"time": "2024-09-03 10:22:15.299"
}
},
"7f4fd414f77915febeb469732ae4b5fc": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.development.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.583"
}
},
"8922cdd711b3060411b079fa8f39ba72": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.development.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.896"
}
},
"90f891576bd575758a3bde4514e86e9c": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.development.qrcode",
"name": "场景码",
"order": "501",
@ -76,7 +109,7 @@
},
"9cd3425d133a3b63b67a3110e25af04d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.development.notice",
"name": "通知公告",
"order": "505",
@ -94,9 +127,16 @@
"time": "2024-09-03 10:22:15.301"
}
},
"9f9581dfeca0595b8c4ff982bb523791": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.development.spendlist",
"time": "2025-04-19 08:28:36.255"
}
},
"ae176612af13a5cdb5b01ece8172651a": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.development.member",
"name": "组织成员",
"order": "102",
@ -106,7 +146,7 @@
},
"b985480805074cd9ce56b1f97dbf6c68": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.development.message",
"name": "消息待办",
"order": "902",
@ -115,7 +155,7 @@
},
"bc7d1f3b02ca339b1baeeda66822784e": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.development.allow",
"name": "权限审批",
"order": "503",
@ -125,7 +165,7 @@
},
"dee424d13ad309aa8ec7f4247072dcb3": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.development.apply",
"name": "权限申请",
"order": "502",
@ -133,9 +173,38 @@
"time": "2024-09-03 10:22:15.303"
}
},
"e3412424662fc4735c37f7a7bda7558a": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.development.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:01.203"
}
},
"e347aded50c684b8e3118ba359a56039": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.development.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.815"
}
},
"e89f61693ccdf4a978b3bc2c1329deca": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.development.quotalist",
"time": "2025-04-19 08:28:36.255"
}
},
"e97ee926a1428c894e9d3e7d086b1e9c": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.development.market",
"name": "人民广场",
"order": "901",
@ -151,5 +220,16 @@
"public": "true",
"time": "2024-10-04 22:31:10.447"
}
},
"f842095ef49f8ab1a3e11b26b1f7391d": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.development.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.817"
}
}
}

View File

@ -18,6 +18,17 @@
"time": "2024-09-03 10:12:53.614"
}
},
"22574299a657140d473f0216b8d83710": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.gonganxitong.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.809"
}
},
"27c6988eeb07c78cbb49aa15c577cfa4": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
@ -28,6 +39,17 @@
"time": "2024-09-03 10:12:53.617"
}
},
"2f80f1821b55a90555f630def20387be": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.gonganxitong.contract",
"name": "在线合同",
"order": "93",
"role": "leader,worker",
"time": "2024-11-25 15:19:53.242"
}
},
"3971882ea4f32c86386ad04b39d3e3d4": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
@ -37,6 +59,28 @@
"time": "2024-09-09 08:51:35.219"
}
},
"55ff6002f602327674ed6d4616023184": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.gonganxitong.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.566"
}
},
"882a999b4a72a9866d9e4eef110d335a": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.gonganxitong.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.799"
}
},
"8ce4dfb877e04e3be5144253fdd5d8ff": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
@ -110,6 +154,17 @@
"time": "2024-09-09 08:51:35.222"
}
},
"cbfda09ef49108ad9addf5117bcb54ce": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.gonganxitong.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:01.193"
}
},
"d86e4e63183c8fae4ceb50498b0bcfde": {
"meta": {
"icons": "https://img.icons8.com/officel/80/categorize.png",
@ -128,9 +183,20 @@
"time": "2024-09-03 10:12:53.668"
}
},
"f24b53f61852f58734f9ef8488705026": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.gonganxitong.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.676"
}
},
"f28c03b5bdbbe92ebc89dabca5e7d4de": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/usr/local/work/20240724-community/src/gonganxitong/member.png",
"index": "web.team.gonganxitong.member",
"name": "组织成员",
"order": "80",

View File

@ -1,7 +1,15 @@
{
"003dd6be7f666b93d80cf0f758880d84": {
"meta": {
"icons": "https://img.icons8.com/officel/80/purchase-order.png",
"index": "web.team.guanlixitong.procurement",
"name": "采购清单",
"time": "2024-11-10 11:04:10.504"
}
},
"030e2a53ca3561a0d0d123c133a88b59": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.guanlixitong.qrcode",
"name": "场景码",
"order": "90",
@ -17,7 +25,7 @@
},
"0521e637b051a0e175a6070eded1bcef": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.guanlixitong.setting",
"name": "服务配置",
"order": "102",
@ -27,16 +35,32 @@
},
"057616b7366e1930ef4e4a921fe45f1f": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.guanlixitong.service",
"name": "服务发现",
"order": "102",
"time": "2024-09-03 10:22:15.279"
}
},
"0721f4589e2e5f0a50b9088471e141a4": {
"meta": {
"icons": "https://img.icons8.com/officel/80/about-us-male--v2.png",
"index": "web.team.guanlixitong.employee",
"name": "员工信息",
"time": "2024-11-10 11:04:10.490"
}
},
"0d1831178568952bdf4f5c6b1587742b": {
"meta": {
"icons": "https://img.icons8.com/officel/80/parse-from-clipboard.png",
"index": "web.team.guanlixitong.resume",
"name": "应聘简历",
"time": "2024-11-10 11:04:10.497"
}
},
"2fd80c581b69c9f67420e793804dbd9f": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.guanlixitong.credit",
"name": "用户名片",
"order": "102",
@ -45,7 +69,7 @@
},
"30bfa47cab4cd689901fd2e1b87eb235": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.guanlixitong.allow",
"name": "权限审批",
"order": "92",
@ -53,9 +77,24 @@
"time": "2024-09-03 10:22:15.271"
}
},
"31e2929e94058b015eadf6e874f956a8": {
"meta": {
"icons": "https://img.icons8.com/officel/80/set-as-resume.png",
"index": "web.team.guanlixitong.recruitment",
"name": "招聘需求",
"time": "2024-11-10 11:04:10.496"
}
},
"45a953c0d57edbfcece5f53e62d04bd3": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.guanlixitong.spendlist",
"time": "2025-04-19 08:28:36.229"
}
},
"5695d50b28872804a01d7c923ee91cd1": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.guanlixitong.member",
"name": "团队成员",
"order": "80",
@ -65,16 +104,27 @@
},
"78d29149539be88d7561b8e17bd65882": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.guanlixitong.market",
"name": "人民广场",
"order": "100",
"time": "2024-09-09 08:51:35.192"
}
},
"7c0eda0a842c79270ebf4917a0a07b9e": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.guanlixitong.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.542"
}
},
"809b63c1819fc3ac1452e3b71889aec5": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.guanlixitong.notice",
"name": "通知公告",
"order": "94",
@ -82,9 +132,20 @@
"time": "2024-09-09 08:51:35.195"
}
},
"8548d5ce3faee7bd508d2fb53d57f35b": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.guanlixitong.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.776"
}
},
"9c18032c5bc252f2986e1b20e7e77db7": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.guanlixitong.event",
"name": "事件流",
"order": "93",
@ -94,25 +155,64 @@
},
"9fffbe375e2d2a1a8e6cb1f341e35b55": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.guanlixitong.recent",
"name": "最近访问",
"order": "101",
"time": "2024-09-03 10:22:15.280"
}
},
"a59e847a365ef89dd35e250e9b663ac3": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.guanlixitong.quotalist",
"time": "2025-04-19 08:28:36.221"
}
},
"ace6350cd663c693ddf47e81625c8a7a": {
"meta": {
"icons": "https://img.icons8.com/officel/80/meeting.png",
"index": "web.team.guanlixitong.interview",
"name": "招聘面试",
"time": "2024-11-10 11:04:10.499"
}
},
"ad9a805bfef319f0704842021bfc17b0": {
"meta": {
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.guanlixitong.conference",
"name": "在线会议",
"time": "2024-11-10 11:04:10.492"
}
},
"af39f30945dafa855548057f4dab3be4": {
"meta": {
"icons": "https://img.icons8.com/officel/80/warehouse.png",
"index": "web.team.guanlixitong.inventory",
"name": "库存物资",
"time": "2024-11-10 11:04:10.493"
}
},
"c27ad1df8aa9059d6018fb5add5ee546": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.guanlixitong.support",
"name": "客服支持",
"order": "103",
"time": "2024-09-03 10:22:15.273"
}
},
"c2fcc269f958a7b4b3bf0e37a2641ed8": {
"meta": {
"icons": "https://img.icons8.com/officel/80/office.png",
"index": "web.team.guanlixitong.equipment",
"name": "办公用品",
"time": "2024-11-10 11:04:10.500"
}
},
"c36d47e2611b0d1e7a14088bc3293d04": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.guanlixitong.apply",
"name": "权限申请",
"order": "91",
@ -120,15 +220,59 @@
"time": "2024-09-03 10:22:15.275"
}
},
"cb1692a3c6b2d0d7da022787e411843b": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.guanlixitong.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:01.173"
}
},
"d25f3f88261ead2a0079415a26aa6853": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.guanlixitong.message",
"name": "消息待办",
"order": "100",
"time": "2024-09-03 10:22:15.274"
}
},
"e2ade31e19fd70911169780be6757fa3": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.guanlixitong.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.769"
}
},
"e595a0bbefbcfaa89f45dd875cc6fe0b": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.guanlixitong.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-10 11:04:10.491"
}
},
"f10df497cdaa6ec48de612ae8cde4c9a": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.guanlixitong.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.639"
}
},
"fa5ff99e330772f88b929de7762a36f1": {
"meta": {
"icons": "https://img.icons8.com/officel/80/goal--v1.png",

View File

@ -1,7 +1,42 @@
{
"03acc6ed03fa47e9639f1e5c459c3b50": {
"meta": {
"auth": "issued",
"icons": "src/operation/activity-grid.png",
"index": "web.team.operation.template",
"name": "云模板",
"order": "2",
"role": "leader,worker",
"time": "2025-03-14 20:51:15.546"
}
},
"03f7f410d292fb30026cbcd99290e943": {
"meta": {
"auth": "issued",
"enable": "false",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.operation.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.520"
}
},
"2511b9e18bf167ae0171c740e8f0513c": {
"meta": {
"auth": "issued",
"enable": "false",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.operation.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.756"
}
},
"3b0ced2e41179097e594b91c3c36536b": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.operation.member",
"name": "组织成员",
"order": "102",
@ -9,18 +44,35 @@
"time": "2024-09-03 10:22:15.741"
}
},
"4282391df391e600e784bc8cae0cc2b8": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.operation.spendlist",
"time": "2025-04-19 08:28:36.214"
}
},
"53b0f8b9867485bb8864f2205e31897e": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.operation.service",
"name": "服务发现",
"order": "904",
"time": "2024-09-03 10:22:15.258"
}
},
"64be90144c205e73b1fc216962d7ad25": {
"meta": {
"auth": "issued",
"icons": "src/operation/activity-grid.png",
"index": "web.team.operation.product",
"name": "云服务",
"order": "5",
"time": "2025-03-05 10:40:39.748"
}
},
"6ca4f1fc571350c2498bc5c1d7ac3563": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.operation.qrcode",
"name": "场景码",
"order": "501",
@ -28,18 +80,32 @@
"time": "2024-09-03 10:22:15.841"
}
},
"7633ddfc1c6052b7dd2f00096248e1f7": {
"700c65f09a19cb53ee5c2dfbb98a5a0b": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"index": "web.team.operation.release",
"name": "发布",
"order": "1",
"time": "2024-09-03 10:22:15.265"
"auth": "issued",
"enable": "false",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.operation.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.566"
}
},
"7abb3b3760a9b686457938511c0ee7df": {
"meta": {
"auth": "issued",
"icons": "src/operation/activity-grid.png",
"index": "web.team.operation.project",
"name": "云项目",
"order": "4",
"role": "leader,worker",
"time": "2025-03-05 10:40:39.740"
}
},
"85c8678d4af08bb0c3e9560155b7c98f": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.operation.event",
"name": "事件流",
"order": "504",
@ -47,9 +113,28 @@
"time": "2024-09-03 10:22:15.264"
}
},
"89a7a6f18c32f37972a916f0aebe2a42": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.operation.quotalist",
"time": "2025-04-19 08:28:36.106"
}
},
"91b0ca086b5b8aa00e84737c4395a19f": {
"meta": {
"auth": "issued",
"enable": "false",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.operation.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.766"
}
},
"aa58390a9fac9f8210eca564d1ad82ff": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.operation.credit",
"name": "用户名片",
"order": "101",
@ -58,16 +143,27 @@
},
"b2d8434f3ab5340408f71c4bf087e3d9": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.operation.recent",
"name": "最近访问",
"order": "903",
"time": "2024-09-03 10:22:15.259"
}
},
"c8159ab932f400dbafa08fb995e16355": {
"meta": {
"auth": "issued",
"icons": "src/operation/activity-grid.png",
"index": "web.team.operation.cluster",
"name": "云集群",
"order": "1",
"role": "leader",
"time": "2025-03-05 10:40:39.838"
}
},
"ca74fb83cfd850b1ca03fe18976c253a": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.operation.message",
"name": "消息待办",
"order": "902",
@ -76,7 +172,7 @@
},
"d2c6f264302bdd5d46beb921f389efda": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.operation.notice",
"name": "通知公告",
"order": "505",
@ -86,7 +182,7 @@
},
"d47d5d11064235734413113c7440af7f": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.operation.allow",
"name": "权限审批",
"order": "503",
@ -94,9 +190,32 @@
"time": "2024-09-03 10:22:15.260"
}
},
"d8f6d139d6a5f9b5aa504702e7777eb3": {
"meta": {
"auth": "issued",
"icons": "src/operation/activity-grid.png",
"index": "web.team.operation.gateway",
"name": "云主机",
"order": "3",
"portal": "true",
"time": "2025-03-05 12:13:06.405"
}
},
"d953e8b2c9159b1f4d32ff1c15793314": {
"meta": {
"auth": "issued",
"enable": "false",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.operation.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.761"
}
},
"dad14d38feac6ebfb61953f8aae393bb": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.operation.market",
"name": "人民广场",
"order": "901",
@ -105,7 +224,7 @@
},
"e0b69dbd47a289ed57d970877000fa40": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.operation.setting",
"name": "服务配置",
"order": "103",
@ -113,9 +232,21 @@
"time": "2024-09-21 08:58:33.495"
}
},
"e9150ed09fcdb4da60f1e9f0d5fe54ea": {
"meta": {
"auth": "issued",
"enable": "false",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.operation.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:01.092"
}
},
"ec25b5c62a4d26688fe114d9b25f7a56": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.operation.support",
"name": "客服支持",
"order": "905",
@ -124,7 +255,7 @@
},
"f7484dd174d63a6800f84d1fb5fbb584": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.operation.apply",
"name": "权限申请",
"order": "502",

View File

@ -1,7 +1,7 @@
{
"1b5f923af5910ea22c451559e7d6a640": {
"meta": {
"icons": "https://img.icons8.com/officel/80/timeline-week.png",
"icons": "src/production/plan.png",
"index": "web.team.production.plan",
"name": "迭代计划",
"order": "1",
@ -10,7 +10,7 @@
},
"247b484fb13394452bc978e5ecad33ff": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.production.apply",
"name": "权限申请",
"order": "502",
@ -18,19 +18,41 @@
"time": "2024-09-03 15:44:28.515"
}
},
"2cc2b9d11344506a6b0bbb0dbdde2d43": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.production.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.425"
}
},
"2cf321f56f8ace96e561bf54f664f276": {
"meta": {
"icons": "https://img.icons8.com/officel/80/communication.png",
"icons": "src/production/issue.png",
"index": "web.team.production.issue",
"name": "产品需求",
"order": "2",
"role": "leader,worker,server",
"portal": "true",
"time": "2024-09-03 15:44:28.509"
}
},
"2f55a878524db4227e7476307269db05": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.production.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:01.083"
}
},
"50dd2633fafc2efb90760b602f1500ea": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.production.notice",
"name": "通知公告",
"order": "505",
@ -40,7 +62,7 @@
},
"53d92f96ed804b0981073cd6fa7121d7": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.production.market",
"name": "人民广场",
"order": "901",
@ -49,7 +71,7 @@
},
"684ebb2576bd4d7024a04693de6aaeab": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.production.recent",
"name": "最近访问",
"order": "903",
@ -58,7 +80,7 @@
},
"6871a5c44a6021f7edaf46cf356266e3": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.production.setting",
"name": "服务配置",
"order": "103",
@ -66,9 +88,16 @@
"time": "2024-09-21 08:58:33.492"
}
},
"6a772ca2070051382a919d62bb784e3a": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.production.spendlist",
"time": "2025-04-19 08:28:36.007"
}
},
"6d06c21df099b1bc6b85fa6ff59ae6d1": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.production.allow",
"name": "权限审批",
"order": "503",
@ -76,9 +105,30 @@
"time": "2024-09-03 15:44:28.507"
}
},
"73b81840f26d2885c065d19e08e923f1": {
"meta": {
"icons": "src/production/design.png",
"index": "web.team.production.design",
"name": "界面设计",
"order": "3",
"role": "leader,worker",
"time": "2025-03-21 08:49:22.166"
}
},
"7cf76afacb83fabb3d6a6ffaf48b6066": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.production.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.589"
}
},
"8efc6b4f9d0d59713215fb5843f8f037": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.production.support",
"name": "客服支持",
"order": "905",
@ -87,17 +137,17 @@
},
"9a1b27391021fe202075fdec5e55011d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/faq.png",
"icons": "src/production/case.png",
"index": "web.team.production.case",
"name": "测试用例",
"order": "4",
"role": "leader,worker,server",
"role": "leader,worker",
"time": "2024-09-12 20:43:01.630"
}
},
"9c8310df39f8423ff77f19652b471a35": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.production.qrcode",
"name": "场景码",
"order": "501",
@ -105,9 +155,27 @@
"time": "2024-09-03 15:44:29.253"
}
},
"a22f30598723eaf9a2f2e3b105ffd7ec": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.production.quotalist",
"time": "2025-04-19 08:28:36.019"
}
},
"a9b5b213c868653f1a060c3231d57e8f": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.production.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.689"
}
},
"af401082a04bff4314523e5ebb69abff": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.production.credit",
"name": "用户名片",
"order": "101",
@ -116,7 +184,7 @@
},
"b7772dfc47e42e8c7e1c07fc1657546a": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.production.message",
"name": "消息待办",
"order": "902",
@ -125,7 +193,7 @@
},
"c27f5383bb62fe30347da4fbac3ff0a8": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.production.event",
"name": "事件流",
"order": "504",
@ -133,20 +201,42 @@
"time": "2024-09-03 15:44:28.512"
}
},
"c9559beab992f8b46b9cfa4a196e61e8": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.production.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.691"
}
},
"c96881ba1b560e55d4d589e7c52033ca": {
"meta": {
"icons": "https://img.icons8.com/officel/80/tasks.png",
"icons": "src/production/task.png",
"index": "web.team.production.task",
"name": "开发任务",
"order": "3",
"public": "true",
"role": "leader,worker,server",
"role": "leader,worker",
"time": "2024-09-12 20:43:01.633"
}
},
"cea1324e3dca123f6560dee5c559a587": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.production.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.484"
}
},
"e10cc3b27f6a9f02fbf22bc58551d862": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.production.service",
"name": "服务发现",
"order": "904",
@ -155,7 +245,7 @@
},
"e4bdcf2bcde46db180cad771406987b5": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.production.member",
"name": "项目成员",
"order": "102",

View File

@ -1,7 +1,18 @@
{
"015b4784c16b63975824abbb3ff4ec9f": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.renzhengshouquan.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-29 21:33:29.660"
}
},
"0d7f068029dbf7f9f0d307070cc3a79b": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.allow",
"name": "权限审批",
"order": "503",
@ -9,9 +20,45 @@
"time": "2024-09-25 08:30:28.774"
}
},
"1c4fee90e6a7bdb8ab6f1ccb23f3273f": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.renzhengshouquan.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-29 21:33:29.663"
}
},
"1d15ae175ffe375630da1466417d2d5d": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.renzhengshouquan.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-29 21:33:29.662"
}
},
"1d5fb457d3223d26afd076c38d7daf66": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.renzhengshouquan.quotalist",
"time": "2025-04-19 08:28:35.980"
}
},
"21887f37ce8dabe4c52648ea096f8e4d": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.renzhengshouquan.spendlist",
"time": "2025-04-19 08:28:35.972"
}
},
"2a065e0a48b909ae79fbb3dd750e1eb5": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "https://img.icons8.com/officel/80/id-verified.png",
"index": "web.team.renzhengshouquan.auth",
"name": "认证授权",
"order": "2",
@ -20,7 +67,7 @@
},
"456d3a031a140d43f54690ea7203628d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.event",
"name": "事件流",
"order": "504",
@ -30,7 +77,7 @@
},
"4cac9ca99ccb8db395f703434647f5f3": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.setting",
"name": "服务配置",
"order": "102",
@ -40,7 +87,7 @@
},
"52fb3a7d85d879b638cc246850b236f6": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.qrcode",
"name": "场景码",
"order": "501",
@ -48,9 +95,20 @@
"time": "2024-09-25 08:30:28.772"
}
},
"6806548eeea33ee2118c520a60bc7e4b": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.renzhengshouquan.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.339"
}
},
"732373815fa26c85ad04dd57ca57db39": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.apply",
"name": "权限申请",
"order": "502",
@ -58,9 +116,30 @@
"time": "2024-09-25 08:30:28.779"
}
},
"79283d05c3eb6007da9adcdc9751f68d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/structured-document-data.png",
"index": "web.team.renzhengshouquan.admin",
"name": "管理后台",
"order": "4",
"role": "leader,worker",
"time": "2024-11-19 16:06:52.858"
}
},
"7a3a6cdf6eebd575950694ee28a8452e": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.renzhengshouquan.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:00.996"
}
},
"83f5f7ed321eeee6827add7a03947102": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "https://img.icons8.com/officel/80/passport.png",
"index": "web.team.renzhengshouquan.profile",
"name": "用户名片",
"order": "3",
@ -69,7 +148,7 @@
},
"89cf6f6cc69c13b7d541a0d61eae66e1": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "https://img.icons8.com/officel/80/identification-documents--v2.png",
"index": "web.team.renzhengshouquan.cert",
"name": "上传证件",
"order": "1",
@ -78,7 +157,7 @@
},
"9e52a4f0a1a8d35c14b40d14b0d9cff1": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.message",
"name": "消息待办",
"order": "902",
@ -87,7 +166,7 @@
},
"a040dfa713a6fa9533b3184244dbbb74": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.support",
"name": "客服支持",
"order": "905",
@ -96,7 +175,7 @@
},
"bfecb55b11fe68186270fe1b4b8de8cf": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.member",
"name": "组织成员",
"order": "101",
@ -104,9 +183,20 @@
"time": "2024-09-25 08:30:28.772"
}
},
"c9eeca8509b5b055149a5593312436cd": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.renzhengshouquan.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.481"
}
},
"d9f55b517f4b2579693523ed3b5bd088": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.market",
"name": "人民广场",
"order": "901",
@ -115,7 +205,7 @@
},
"e038450591f3c8e7babc0c21b1c6fa6d": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.recent",
"name": "最近访问",
"order": "903",
@ -124,7 +214,7 @@
},
"ecfb11fad5b4bdf21384e2e1ff571598": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.notice",
"name": "通知公告",
"order": "505",
@ -134,7 +224,7 @@
},
"f669e15e1c1c9da2bd3ea0c58abc0bd3": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.credit",
"name": "用户名片",
"order": "102",
@ -143,7 +233,7 @@
},
"f6b093d122ff3cec363b00093e0a6f19": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.renzhengshouquan.service",
"name": "服务发现",
"order": "904",

View File

@ -1,7 +1,14 @@
{
"0f24ae224b99c8d65e550cd9528468f4": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/spendlist.png",
"index": "web.team.storage.spendlist",
"time": "2025-04-19 08:28:35.967"
}
},
"11eb042ebed16b7ab0a8a89ac55affb1": {
"meta": {
"icons": "https://img.icons8.com/officel/80/property-with-timer.png",
"icons": "/p/src/gonganxitong/event.png?pod=20240724-community",
"index": "web.team.storage.event",
"name": "事件流",
"order": "504",
@ -11,7 +18,7 @@
},
"2812f9176629b9966be481676fb3aee5": {
"meta": {
"icons": "https://img.icons8.com/officel/80/multiple-smartphones.png",
"icons": "/p/src/gonganxitong/recent.png?pod=20240724-community",
"index": "web.team.storage.recent",
"name": "最近访问",
"order": "903",
@ -20,7 +27,7 @@
},
"351e876ab886708d42b1d82d00cb3bc3": {
"meta": {
"icons": "https://img.icons8.com/officel/80/square.png",
"icons": "/p/src/gonganxitong/market.png?pod=20240724-community",
"index": "web.team.storage.market",
"name": "人民广场",
"order": "901",
@ -29,7 +36,7 @@
},
"38f2721b02a7cf2074f9c3ce78aa6e29": {
"meta": {
"icons": "https://img.icons8.com/officel/80/qr-code.png",
"icons": "/p/src/gonganxitong/qrcode.png?pod=20240724-community",
"index": "web.team.storage.qrcode",
"name": "场景码",
"order": "501",
@ -37,9 +44,20 @@
"time": "2024-09-17 21:19:56.161"
}
},
"3c55e6938bedf9904dbd8a6b3a551824": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/video-conference.png",
"index": "web.team.storage.meeting",
"name": "在线会议",
"order": "91",
"role": "leader,worker",
"time": "2024-11-20 22:03:43.464"
}
},
"44e0cc566504640e376a20a3eb26e6d6": {
"meta": {
"icons": "https://img.icons8.com/officel/80/person-at-home.png",
"icons": "/p/src/gonganxitong/member.png?pod=20240724-community",
"index": "web.team.storage.member",
"name": "网盘成员",
"order": "102",
@ -47,9 +65,20 @@
"time": "2024-09-17 21:19:56.263"
}
},
"4b2a240e9f7321535b5acd39fa889b7e": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-store.png",
"index": "web.team.storage.goodslist",
"name": "在线商城",
"order": "91",
"role": "leader,worker",
"time": "2024-12-05 08:12:26.237"
}
},
"4c837d128ab03d59c8479b695276828c": {
"meta": {
"icons": "https://img.icons8.com/officel/80/customer-support.png",
"icons": "/p/src/gonganxitong/support.png?pod=20240724-community",
"index": "web.team.storage.support",
"name": "客服支持",
"order": "905",
@ -58,7 +87,7 @@
},
"5bfbd386cce531816ef93117ce33ff51": {
"meta": {
"icons": "https://img.icons8.com/officel/80/settings--v1.png",
"icons": "/p/src/gonganxitong/setting.png?pod=20240724-community",
"index": "web.team.storage.setting",
"name": "服务配置",
"order": "103",
@ -68,7 +97,7 @@
},
"618ea5c219d7eb5e194b6eea12853281": {
"meta": {
"icons": "https://img.icons8.com/officel/80/receipt-approved.png",
"icons": "/p/src/gonganxitong/allow.png?pod=20240724-community",
"index": "web.team.storage.allow",
"name": "权限审批",
"order": "503",
@ -76,6 +105,13 @@
"time": "2024-09-17 21:19:56.263"
}
},
"8bd4c73beb0edbf0a185a6327c8d1aba": {
"meta": {
"icons": "/root/2025-web/usr/local/work/20240724-community/src/gonganxitong/quotalist.png",
"index": "web.team.storage.quotalist",
"time": "2025-04-19 08:28:35.877"
}
},
"9b56f892d867dde5e6b65fa81d24a328": {
"meta": {
"icons": "https://img.icons8.com/officel/80/user-folder.png",
@ -87,7 +123,7 @@
},
"b4ff2685fd26c4c952f94986c588b34a": {
"meta": {
"icons": "https://img.icons8.com/officel/80/edit-property.png",
"icons": "/p/src/gonganxitong/apply.png?pod=20240724-community",
"index": "web.team.storage.apply",
"name": "权限申请",
"order": "502",
@ -97,16 +133,38 @@
},
"c3574c11edb3e5e912c39adbeeb04f26": {
"meta": {
"icons": "https://img.icons8.com/officel/80/test-partial-passed.png",
"icons": "/p/src/gonganxitong/message.png?pod=20240724-community",
"index": "web.team.storage.message",
"name": "消息待办",
"order": "902",
"time": "2024-09-17 21:19:56.163"
}
},
"ceaca87cf0d112aec124ad24298e189e": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/ios-photos.png",
"index": "web.team.storage.photo",
"name": "在线相册",
"order": "95",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.564"
}
},
"d4929122bd93a197e2b912b93c951646": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/agreement.png",
"index": "web.team.storage.contract",
"name": "在线合同",
"order": "94",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.485"
}
},
"d9bdb3105dda162dd303f87e5d7bb301": {
"meta": {
"icons": "https://img.icons8.com/officel/80/passport.png",
"icons": "/p/src/gonganxitong/credit.png?pod=20240724-community",
"index": "web.team.storage.credit",
"name": "用户名片",
"order": "101",
@ -115,21 +173,43 @@
},
"de46b4a43370c18fc02cb039592ece22": {
"meta": {
"icons": "https://img.icons8.com/officel/80/activity-grid.png",
"icons": "/p/src/gonganxitong/service.png?pod=20240724-community",
"index": "web.team.storage.service",
"name": "服务发现",
"order": "904",
"time": "2024-09-17 21:19:56.262"
}
},
"f005721298281995921aab3079f9f7e5": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/online-payment-with-a-credit-card.png",
"index": "web.team.storage.paymentlist",
"name": "在线支付",
"order": "92",
"role": "leader,worker",
"time": "2024-11-23 17:07:00.983"
}
},
"f55ae08834fc5fe3a334f35ee0bc8572": {
"meta": {
"icons": "https://img.icons8.com/officel/80/commercial.png",
"icons": "/p/src/gonganxitong/notice.png?pod=20240724-community",
"index": "web.team.storage.notice",
"name": "通知公告",
"order": "505",
"role": "leader",
"time": "2024-09-17 21:19:56.160"
}
},
"f6f77c7a5e247a742c2699564c4507a1": {
"meta": {
"auth": "issued",
"icons": "https://img.icons8.com/officel/80/documents.png",
"index": "web.team.storage.document",
"name": "在线文档",
"order": "93",
"role": "leader,worker",
"time": "2024-11-28 17:54:45.486"
}
}
}