diff --git a/README.md b/README.md
index 84f7585..5df34c9 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,17 @@ Composer
1. 修改./src/config.js,将crossDomain 值改为‘false’
2. 修改./vue.config.js,将DEV_URL的值改为接口的访问地址
3. 重启启动项目
+8. 消息推送
+ 1. 后端
+ 1. 进入application/common/Plugins/GateWayWorker
+ 2. 修改config.php,修改 SERVER_ADDRESS 的值为内网IP地址。端口号根据情况需改,注意服务器要放行对应的端口
+ 3. 如果是HTTPS协议,需要开启SSL支持
+ 4. Windows环境下,直接运行start_for_win.bat文件
+ 5. Linux环境下,运行 bash start.sh 启动服务,运行 bash stop.sh 终止服务
+ 2. 前端
+ 1. 进入 src/config/config.js
+ 2.WS_URI 地址修改为相应的ip地址。如果使用https,不能写ip需要写域名
+
### 鼓励一下 ###
diff --git a/src/api/common/common.js b/src/api/common/common.js
index 59ae8fc..f863d9f 100644
--- a/src/api/common/common.js
+++ b/src/api/common/common.js
@@ -8,6 +8,14 @@ export function checkInstall() {
return $http.post('index/index/checkInstall');
}
+export function inviteInfo(inviteCode) {
+ return $http.post('project/invite_link/_read', {inviteCode: inviteCode});
+}
+export function createInviteLink(data) {
+ return $http.post('project/invite_link/save', data);
+}
+
+
export function notifyOverview(to) {
return $http.post('index/notify/listTypeFormat', {to: to});
}
diff --git a/src/api/projectMember.js b/src/api/projectMember.js
index 46c131a..743483f 100644
--- a/src/api/projectMember.js
+++ b/src/api/projectMember.js
@@ -7,6 +7,9 @@ export function searchInviteMember(keyword, code) {
export function inviteMember(memberCode, code) {
return $http.post('project/project_member/inviteMember', {memberCode: memberCode, projectCode: code});
}
+export function _joinByInviteLink(inviteCode) {
+ return $http.post('project/project_member/_joinByInviteLink', {inviteCode: inviteCode});
+}
export function removeMember(memberCode, code) {
return $http.post('project/project_member/removeMember', {memberCode: memberCode, projectCode: code});
}
diff --git a/src/api/task.js b/src/api/task.js
index af4df5a..b4ab347 100644
--- a/src/api/task.js
+++ b/src/api/task.js
@@ -7,6 +7,7 @@ export function list(data) {
export function selfList(data) {
return $http.post('project/task/selfList', data);
}
+
export function taskSources(data) {
return $http.post('project/task/taskSources', data);
}
@@ -39,6 +40,10 @@ export function assignTask(data) {
return $http.post('project/task/assignTask', data);
}
+export function batchAssignTask(data) {
+ return $http.post('project/task/batchAssignTask', data);
+}
+
export function read(code) {
return $http.post('project/task/read', {taskCode: code});
}
@@ -47,9 +52,14 @@ export function taskDone(code, done) {
return $http.post('project/task/taskDone', {taskCode: code, done: done});
}
+export function setPrivate(code, isPrivate) {
+ return $http.post('project/task/setPrivate', {taskCode: code, private: isPrivate});
+}
+
export function recycle(code) {
return $http.post('project/task/recycle', {taskCode: code});
}
+
export function recycleBatch(data) {
return $http.post('project/task/recycleBatch', data);
}
diff --git a/src/api/user.js b/src/api/user.js
index 7663ede..2a7cc75 100644
--- a/src/api/user.js
+++ b/src/api/user.js
@@ -3,19 +3,23 @@ import $http from '@/assets/js/http'
export async function Login(data) {
return $http.post('project/login', data);
}
+
export function register(data) {
return $http.post('project/login/register', data);
}
+
export function getCaptcha() {
return $http.post('project/login/getCaptcha');
}
+
export function changeCurrentOrganization(organizationCode) {
- return $http.post('project/index/changeCurrentOrganization', {organizationCode:organizationCode});
+ return $http.post('project/index/changeCurrentOrganization', {organizationCode: organizationCode});
}
export function list(data) {
return $http.post('project/account', data);
}
+
export function forbid(accountCode) {
return $http.post('project/account/forbid', {accountCode: accountCode, status: 0});
}
@@ -23,26 +27,43 @@ export function forbid(accountCode) {
export function resume(accountCode) {
return $http.post('project/account/resume', {accountCode: accountCode, status: 1});
}
+
export function doAccount(data) {
let url = 'project/account/add';
- if (data.id) {
+ if (data.code) {
url = 'project/account/edit';
}
return $http.post(url, data);
}
+
export function auth(id, auth) {
return $http.post('project/account/auth', {id: id, auth: auth});
}
+
export function del(accountCode) {
return $http.post('project/account/del', {accountCode: accountCode});
}
+
export function info($id) {
return $http.post('project/index/info', {id: $id});
}
+export function read(code) {
+ return $http.post('project/account/read', {code: code});
+}
+
+export function editAccount(data) {
+ return $http.post('project/account/edit', data);
+}
+
export function editPersonal(data) {
return $http.post('project/index/editPersonal', data);
}
+
export function editPassword(data) {
return $http.post('project/index/editPassword', data);
}
+
+export function _joinByInviteLink(inviteCode) {
+ return $http.post('project/account/_joinByInviteLink', {inviteCode: inviteCode});
+}
diff --git a/src/assets/css/components/base.less b/src/assets/css/components/base.less
index 6b1818c..8f65939 100644
--- a/src/assets/css/components/base.less
+++ b/src/assets/css/components/base.less
@@ -15,49 +15,64 @@ body {
color: rgba(0, 0, 0, 0.45);
font-weight: 400;
}
-.text-grey{
+
+.text-grey {
color: grey;
}
-.text-default{
+
+.text-default {
color: #333;
}
-.text-primary{
+
+.text-primary {
color: @primary-color;
}
-.text-info{
+
+.text-info {
color: @info-color;
}
-.text-success{
+
+.text-success {
color: @success-color;
}
-.text-processing{
+
+.text-processing {
color: @processing-color;
}
-.text-error{
+
+.text-error {
color: @error-color;
}
-.text-highlight{
+
+.text-highlight {
color: @highlight-color;
}
-.text-warning{
+
+.text-warning {
color: @warning-color;
}
-.text-normal{
+
+.text-normal {
color: @normal-color;
}
-.text-center{
+
+.text-center {
text-align: center;
}
-.text-right{
+
+.text-right {
text-align: right;
}
-.text-left{
+
+.text-left {
text-align: left;
}
+
//Input
-.ant-input-lg{
+.ant-input-lg {
font-size: 14px;
}
+
.ant-select-lg {
font-size: 14px;
}
@@ -65,18 +80,21 @@ body {
//Button
.action-btn {
margin-top: 12px;
- .cancel-text{
+
+ .cancel-text {
margin-right: 12px;
}
+
button {
margin-right: 4px;
}
}
-.group-btn,.submit-set {
- .cancel-text{
+.group-btn, .submit-set {
+ .cancel-text {
margin-right: 12px;
}
+
button {
margin-right: 4px;
}
@@ -84,10 +102,12 @@ body {
.middle-btn {
min-width: 66px;
+ //min-height: 42px;
//min-width: 90px;
//height: 35px !important;
}
-.ant-btn-lg{
+
+.ant-btn-lg {
font-size: 14px;
}
@@ -106,18 +126,22 @@ body {
.table-list {
.item {
display: inline-block;
+
&.row-img {
img {
width: 85px;
height: 85px;
}
}
+
&.row-title {
margin-left: 12px;
vertical-align: middle;
width: 75%;
+
.title {
margin-bottom: 0;
+
&.title-name {
padding: 5px 24px 5px 5px;
color: @primary-color;
@@ -125,14 +149,17 @@ body {
}
}
}
+
.edit-content {
.prefix {
position: absolute;
line-height: 2.3;
}
+
.editable-cell {
width: 115px;
}
+
&.price {
.editable-cell-input-wrapper, .editable-cell-text-wrapper {
padding-left: 15px;
@@ -142,9 +169,10 @@ body {
}
//Drowdown
-.ant-dropdown-menu-item{
+.ant-dropdown-menu-item {
color: grey;
}
+
.field-right-menu {
width: 240px;
@@ -186,19 +214,22 @@ body {
}
//Modal
-.ant-modal{
+.ant-modal {
top: 50px;
}
-.scroll-modal{
- .ant-modal-body{
+
+.scroll-modal {
+ .ant-modal-body {
padding-bottom: 24px;
height: 70vh;
}
- .modal-content{
+
+ .modal-content {
padding: 0 24px;
height: 100%;
}
- .modal-footer{
+
+ .modal-footer {
position: fixed;
bottom: 13vh;
background: #FFF;
@@ -206,11 +237,26 @@ body {
}
}
-.hidden{
+.task-detail-modal {
+ width: 1200px;
+
+ &.ant-modal {
+ padding-bottom: 0;
+ }
+
+ .ant-modal-content {
+ .ant-modal-body {
+ padding: 0;
+ }
+
+ }
+}
+
+.hidden {
display: block;
}
-.project-navigation{
+.project-navigation {
border-bottom: 1px solid #D9D9D9;
z-index: 1;
background-color: #F5F5F5;
@@ -218,35 +264,42 @@ body {
position: fixed;
width: 100%;
}
-.project-navigation .ivu-breadcrumb-item-separator{
+
+.project-navigation .ivu-breadcrumb-item-separator {
color: #383838;
}
-.project-navigation .ivu-breadcrumb > span:last-child{
- font-weight:normal;
+
+.project-navigation .ivu-breadcrumb > span:last-child {
+ font-weight: normal;
}
-.project-navigation .project-nav-header{
+
+.project-navigation .project-nav-header {
position: absolute;
z-index: 2;
left: 0;
height: 50px;
margin: 0;
padding: 15px;
- .nav-title{
+
+ .nav-title {
font-size: 15px;
margin-right: 12px;
}
- .actions{
+
+ .actions {
cursor: pointer;
margin-right: 12px;
}
}
+
.project-navigation .nav-underscore {
position: relative;
height: 50px;
border: none;
margin-bottom: 0;
}
-.project-navigation .nav-body{
+
+.project-navigation .nav-body {
position: relative;
white-space: nowrap;
z-index: 1;
@@ -257,14 +310,17 @@ body {
-ms-flex-pack: center;
justify-content: center;
}
+
.project-navigation .nav-body .nav-wrapper.nav > li {
z-index: 2;
padding: 0 20px;
}
+
.project-navigation .nav-underscore > li {
list-style: none;
float: left;
}
+
.project-navigation .nav-underscore > li a {
display: inline-block;
position: relative;
@@ -275,6 +331,7 @@ body {
font-size: 15px;
font-weight: normal;
}
+
.project-navigation .nav-body .nav-wrapper.nav > li .app[data-app=tasks] {
position: relative;
float: left;
@@ -283,9 +340,11 @@ body {
text-overflow: ellipsis;
white-space: nowrap;
}
+
.project-navigation .nav-underscore > li > a:hover {
background-color: inherit;
}
+
.project-navigation .nav-underscore > li > a:after {
position: absolute;
left: 0;
@@ -296,6 +355,7 @@ body {
content: '';
opacity: 0;
}
+
.project-navigation .nav-underscore > li > a:hover:after, .project-navigation .nav-underscore > .actives > a:after {
border-width: 3px;
opacity: 1;
diff --git a/src/assets/css/components/task.less b/src/assets/css/components/task.less
index ee5382b..a636491 100644
--- a/src/assets/css/components/task.less
+++ b/src/assets/css/components/task.less
@@ -581,6 +581,11 @@
border-radius: 50%;
}
+.disabled {
+ cursor: not-allowed;
+ color: rgba(0, 0, 0, 0.45);
+}
+
.task.task-card.done .check-box, .task.task-card.done .task-content-set {
opacity: 0.64;
filter: alpha(opacity=64);
@@ -602,6 +607,7 @@
.task .check-box.disabled {
border-color: #ccc !important;
background-color: #f5f5f5;
+ cursor: not-allowed;
}
.children-task-list .task .check-box {
diff --git a/src/assets/js/notify.js b/src/assets/js/notify.js
index ac541b9..171bc2c 100644
--- a/src/assets/js/notify.js
+++ b/src/assets/js/notify.js
@@ -2,87 +2,87 @@
* Created by vilson on 17/6/4.
*/
export const showMsgNotification = (title, msg, $opt = {}) => {
- let options = {
- body: msg,
- icon: $opt.icon || "http://static.vilson.xyz/preview.jpg",
- showTime: $opt.showTime || 15000,
- onclick: $opt.onclick,
- onshow: $opt.onshow,
- onerror: $opt.onerror,
- onclose: $opt.onclose,
- };
- let Notification = window.Notification || window.mozNotification || window.webkitNotification;
- console.log(Notification.permission)
- if (Notification && Notification.permission === "granted") {
- let instance = new Notification(title, options);
- instance.onclick = function () {
- // Something to do
- if (typeof options.onclick === 'function') {
- options.onclick(instance)
- }
- // window.location.href = instance.icon
+ let options = {
+ body: msg,
+ icon: $opt.icon || "http://static.vilson.xyz/preview.jpg",
+ showTime: $opt.showTime || 15000,
+ onclick: $opt.onclick,
+ onshow: $opt.onshow,
+ onerror: $opt.onerror,
+ onclose: $opt.onclose,
};
- instance.onerror = function () {
- // Something to do
- if (typeof options.onerror === 'function') {
- options.onerror(instance)
- }
- };
- instance.onshow = function () {
- // Something to do
- if (typeof options.onshow === 'function') {
- options.onshow(instance)
- }
- setTimeout(function () {
- instance.close();
- }, options.showTime)
- };
- instance.onclose = function () {
- // Something to do
- if (typeof options.onclose === 'function') {
- options.onclose(instance)
- }
- };
- } else if (Notification && Notification.permission !== "denied") {
- Notification.requestPermission(function (status) {
- if (Notification.permission !== status) {
- Notification.permission = status;
- }
- // If the user said okay
- if (status === "granted") {
+ let Notification = window.Notification || window.mozNotification || window.webkitNotification;
+ console.log(Notification.permission);
+ if (Notification && Notification.permission === "granted") {
let instance = new Notification(title, options);
instance.onclick = function () {
- // Something to do
- if (typeof options.onclick === 'function') {
- options.onclick(instance)
- }
+ // Something to do
+ if (typeof options.onclick === 'function') {
+ options.onclick(instance)
+ }
+ // window.location.href = instance.icon
};
instance.onerror = function () {
- // Something to do
- if (typeof options.onerror === 'function') {
- options.onerror(instance)
- }
+ // Something to do
+ if (typeof options.onerror === 'function') {
+ options.onerror(instance)
+ }
};
instance.onshow = function () {
- // Something to do
- if (typeof options.onshow === 'function') {
- options.onshow(instance)
- }
- setTimeout(function () {
- instance.close();
- }, options.showTime)
+ // Something to do
+ if (typeof options.onshow === 'function') {
+ options.onshow(instance)
+ }
+ setTimeout(function () {
+ instance.close();
+ }, options.showTime)
};
instance.onclose = function () {
- // Something to do
- if (typeof options.onclose === 'function') {
- options.onclose(instance)
- }
+ // Something to do
+ if (typeof options.onclose === 'function') {
+ options.onclose(instance)
+ }
};
- } else {
- return false
- }
- });
- } else {
- return false;
- }
-}
+ } else if (Notification && Notification.permission !== "denied") {
+ Notification.requestPermission(function (status) {
+ if (Notification.permission !== status) {
+ Notification.permission = status;
+ }
+ // If the user said okay
+ if (status === "granted") {
+ let instance = new Notification(title, options);
+ instance.onclick = function () {
+ // Something to do
+ if (typeof options.onclick === 'function') {
+ options.onclick(instance)
+ }
+ };
+ instance.onerror = function () {
+ // Something to do
+ if (typeof options.onerror === 'function') {
+ options.onerror(instance)
+ }
+ };
+ instance.onshow = function () {
+ // Something to do
+ if (typeof options.onshow === 'function') {
+ options.onshow(instance)
+ }
+ setTimeout(function () {
+ instance.close();
+ }, options.showTime)
+ };
+ instance.onclose = function () {
+ // Something to do
+ if (typeof options.onclose === 'function') {
+ options.onclose(instance)
+ }
+ };
+ } else {
+ return false
+ }
+ });
+ } else {
+ return false;
+ }
+};
diff --git a/src/components/Trend/Trend.vue b/src/components/Trend/Trend.vue
new file mode 100644
index 0000000..1be8e91
--- /dev/null
+++ b/src/components/Trend/Trend.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Trend/index.js b/src/components/Trend/index.js
new file mode 100644
index 0000000..761366d
--- /dev/null
+++ b/src/components/Trend/index.js
@@ -0,0 +1,3 @@
+import Trend from './Trend.vue'
+
+export default Trend
\ No newline at end of file
diff --git a/src/components/Trend/index.less b/src/components/Trend/index.less
new file mode 100644
index 0000000..d020c06
--- /dev/null
+++ b/src/components/Trend/index.less
@@ -0,0 +1,42 @@
+@import "../index";
+
+@trend-prefix-cls: ~"@{ant-pro-prefix}-trend";
+
+.@{trend-prefix-cls} {
+ display: inline-block;
+ font-size: @font-size-base;
+ line-height: 22px;
+
+ .up,
+ .down {
+ margin-left: 4px;
+ position: relative;
+ top: 1px;
+
+ i {
+ font-size: 12px;
+ transform: scale(0.83);
+ }
+ }
+
+ .item-text {
+ display: inline-block;
+ margin-left: 8px;
+ color: rgba(0,0,0,.85);
+ }
+
+ .up {
+ color: @red-6;
+ }
+ .down {
+ color: @green-6;
+ top: -1px;
+ }
+
+ &.reverse-color .up {
+ color: @green-6;
+ }
+ &.reverse-color .down {
+ color: @red-6;
+ }
+}
diff --git a/src/components/Trend/index.md b/src/components/Trend/index.md
new file mode 100644
index 0000000..8881f0e
--- /dev/null
+++ b/src/components/Trend/index.md
@@ -0,0 +1,45 @@
+# Trend 趋势标记
+
+趋势符号,标记上升和下降趋势。通常用绿色代表“好”,红色代表“不好”,股票涨跌场景除外。
+
+
+
+引用方式:
+
+```javascript
+import Trend from '@/components/Trend'
+
+export default {
+ components: {
+ Trend
+ }
+}
+```
+
+
+
+## 代码演示 [demo](https://pro.loacg.com/test/home)
+
+```html
+5%
+```
+或
+```html
+
+ 工资
+ 5%
+
+```
+或
+```html
+5%
+```
+
+
+## API
+
+| 参数 | 说明 | 类型 | 默认值 |
+|----------|------------------------------------------|-------------|-------|
+| flag | 上升下降标识:`up|down` | string | - |
+| reverseColor | 颜色反转 | Boolean | false |
+
diff --git a/src/components/chart/ChartCard.vue b/src/components/chart/ChartCard.vue
new file mode 100644
index 0000000..0d83f98
--- /dev/null
+++ b/src/components/chart/ChartCard.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/chart/MiniProgress.vue b/src/components/chart/MiniProgress.vue
new file mode 100644
index 0000000..3e548bb
--- /dev/null
+++ b/src/components/chart/MiniProgress.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
diff --git a/src/components/chart/RankList.vue b/src/components/chart/RankList.vue
new file mode 100644
index 0000000..e62adb6
--- /dev/null
+++ b/src/components/chart/RankList.vue
@@ -0,0 +1,77 @@
+
+
+
{{ title }}
+
+ -
+ {{ index + 1 }}
+ {{ item.name }}
+ {{ item.total }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/index.less b/src/components/index.less
new file mode 100644
index 0000000..df1feb4
--- /dev/null
+++ b/src/components/index.less
@@ -0,0 +1,4 @@
+@import "~ant-design-vue/lib/style/index";
+
+// The prefix to use on all css classes from ant-pro.
+@ant-pro-prefix : ant-pro;
diff --git a/src/components/layout/header/HeaderNotice.vue b/src/components/layout/header/HeaderNotice.vue
index 32a0db8..24f21f4 100644
--- a/src/components/layout/header/HeaderNotice.vue
+++ b/src/components/layout/header/HeaderNotice.vue
@@ -1,79 +1,88 @@
-