Browse Source

Merge branch 'feat' of ssh://101.201.226.163:50022/TALL/TALL-MUI-4 into feat

test2
song 4 years ago
parent
commit
6e5dc5dade
  1. 26
      App.vue
  2. 57
      CHANGELOG.md
  3. 12
      apis/tall.js
  4. 5
      common/js/config.js
  5. 70
      common/styles/tailwind.scss
  6. 23
      common/styles/theme/default.scss
  7. 4
      components/Globals/Globals.vue
  8. 19
      components/ModalBox/ModalBox.vue
  9. 343
      components/PrettyExchange/PrettyExchange.vue
  10. 17
      components/Projects/ProjectItem.vue
  11. 6
      components/Projects/Projects.vue
  12. 91
      components/Reviewer/Reviewer.vue
  13. 24
      hooks/user/userMixin.js
  14. 8
      manifest.json
  15. 28
      pages.json
  16. 121
      pages/index/index.vue
  17. 26
      pages/submitlist/submitlist.vue
  18. 10
      pages/user/accountLogin.vue
  19. 18
      pages/user/agreement.vue
  20. 80
      pages/user/login.vue
  21. 153
      pages/user/rigister.vue
  22. 186
      plugins/p-deliver/p-deliver.vue
  23. 9
      plugins/p-task-title/p-task-title.vue
  24. 69
      project.config.json
  25. 2
      store/socket/actions.js
  26. 2
      store/user/actions.js
  27. 18
      utils/cacheAndRequest.js
  28. 11
      utils/request.js

26
App.vue

@ -1,6 +1,4 @@
<script>
// import { mapState } from 'vuex';
export default {
// computed: {
// ...mapState(['theme']),
@ -16,17 +14,25 @@ export default {
async onLaunch(options) {
// this.loadTheme();
console.log('onLaunch options: ', options);
// console.log('onLaunch options: ', options);
this.checkNetwork(); //
this.getSystemInfo(); //
await this.syncLocalDataToStore(options.query.u); // localStoragestore
const token = await this.getToken();
if (!token) {
this.$ui.showToast('获取用户信息失败, 请登录');
// TODO:
return;
const token = this.$store.state.user.token || this.$storage.getStorageSync('anyringToken') || '';
if (token) {
this.$store.commit('user/setToken', token);
}
this.noPhone(this.$store.state.user.phone);
// if (!token) {
// this.$ui.showToast(', ');
// // TODO:
// return;
// }
// await this.syncLocalDataToStore(options.query.u); // localStoragestore
// token = await this.getToken();
// this.noPhone(this.$store.state.user.phone);
this.$store.dispatch('socket/initSocket');
},

57
CHANGELOG.md

@ -12,40 +12,57 @@
- | 手机号登录 | [a198527](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a198527)
- | 手机号登录 | [8f455da](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8f455da)
- | 手机号登录 | [565585b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/565585b)
- | 表单验证 | [8f3bc1e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8f3bc1e)
- | 插件的填写提交,编辑与删除 | [84390d5](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/84390d5)
- | 插件的填写与提交,修改与删除 | [d461252](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/d461252)
- | 插件面板分开显示 | [fb5e86b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/fb5e86b)
- | 日历页添加 | [1b46a91](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1b46a91)
- | 登录、日历页小绿点、二级项目列表 | [e676cf0](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/e676cf0)
- | 更新代码 | [392c8cc](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/392c8cc)
- | 获取手机唯一码 | [3f60cf8](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3f60cf8)
- | 日历页首页 | [561c8e6](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/561c8e6)
- | 时间轴展示 | [8b1b380](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8b1b380)
- | 日历页添加 | [1b46a91](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1b46a91)
- | 时间轴接口 | [a95d005](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a95d005)
- | 时间轴页面 | [e926b75](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/e926b75)
- | 更新代码 | [392c8cc](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/392c8cc)
- | 时间轴展示 | [8b1b380](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8b1b380)
- | 使用uview完成api请求 | [1b3efd8](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/1b3efd8)
- | 手机号登录 | [a198527](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a198527)
- | 手机号登录 | [8f455da](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8f455da)
- | 手机号登录 | [565585b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/565585b)
- | 添加 timeline | [72dad2b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/72dad2b)
- | 表单验证 | [8f3bc1e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8f3bc1e)
- | 账户名密码登录 | [ebf456e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/ebf456e)
- | 项目操作面板 | [3beb05e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3beb05e)
- | 项目列表 | [a52e6d5](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a52e6d5)
- | 项目列表新 | [88cf48d](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/88cf48d)
- | 项目操作面板 | [3beb05e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3beb05e)
- | 账户名密码登录 | [ebf456e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/ebf456e)
- | 注册、用户协议 | [68e9189](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/68e9189)
- | app.vue | [970cf9a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/970cf9a)
- | first commit | [8dc26de](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8dc26de)
project | 日常任务面板添加 | [b3f16ff](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/b3f16ff)
theme | theme demo | [9175758](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/9175758)
- | vue3 | [12ed2ad](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/12ed2ad)
### 🎨 代码样式
范围|描述|commitId
--|--|--
- | calender格式及细节调整 | [db9602b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/db9602b)
- | 更新代码 | [aa6093a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/aa6093a)
- | 细节调整 | [bdd5f87](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/bdd5f87)
- | calender格式及细节调整 | [db9602b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/db9602b)
### 🐛 Bug 修复
范围|描述|commitId
--|--|--
- | 插件接口修改 | [53c6b90](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/53c6b90)
- | 解决warning | [dcb0079](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/dcb0079)
- | 删除多余的引入 | [050b12a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/050b12a)
- | 上个提交导致的bug | [7524b24](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/7524b24)
- | 时间轴任务 | [98abdf6](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/98abdf6)
- | 项目列表排序 | [ad0ce75](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/ad0ce75)
- | 修复一些内容 | [3cdb1ce](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3cdb1ce)
- | 子组件传参 | [489e218](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/489e218)
app.vue | 修复获取token报错的问题 | [9120d54](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/9120d54)
createTask | 修复createTask v-model的问题 | [b20d3f0](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/b20d3f0)
- | defineExpose, defineEmits不需要引入 | [902cacc](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/902cacc)
- | 修复一些内容 | [3cdb1ce](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/3cdb1ce)
- | 删除多余的引入 | [050b12a](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/050b12a)
- | 插件接口修改 | [53c6b90](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/53c6b90)
- | 时间轴任务 | [98abdf6](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/98abdf6)
- | 解决warning | [dcb0079](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/dcb0079)
### 📦 持续集成
@ -58,15 +75,26 @@
- | 更新drone.yml | [a57d598](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a57d598)
- | 测试ci | [6ab95f8](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/6ab95f8)
- | 测试ci' | [d25f2a7](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/d25f2a7)
- | 更新drone.yml | [63ec5a3](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/63ec5a3)
- | 更新drone.yml | [a57d598](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/a57d598)
- | 添加drone.yml | [9fbae89](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/9fbae89)
- | 修改.drone.yml | [f5b52e3](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/f5b52e3)
- | ci update | [d38262e](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/d38262e)
- | drone | [8cddc7b](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/8cddc7b)
### 🔧 测试
范围|描述|commitId
--|--|--
- | 手机号登录 | [5ede115](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/5ede115)
### 🔨 代码重构
范围|描述|commitId
--|--|--
- | project init 重构 | [2457a87](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/2457a87)
- | 重构project init 部分 | [c7bf2df](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/c7bf2df)
- | 项目列表 | [0486e98](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/0486e98)
- | 重构project init 部分 | [c7bf2df](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/c7bf2df)
- | project init 重构 | [2457a87](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/2457a87)
### 🚀 性能优化
@ -84,4 +112,3 @@
范围|描述|commitId
--|--|--
- | Initial commit | [52b8f49](https://101.201.226.163:50022/TALL/TALL-MUI-4/commits/52b8f49)

12
apis/tall.js

@ -1,14 +1,16 @@
import Config from '@/common/js/config.js'
const apiUrl = Config.apiUrl;
const tall = `${apiUrl}/tall3/v3.0`;
const tall1 = `http://101.201.226.163/gateway/ptos`;
// const apiUrl = Config.apiUrl;
const apiUrl = Config.apiUrlNew;
// const tall = `${apiUrl}/tall3/v3.0`;
const tall = `${apiUrl}/ptostall`;
export function setupTall(app) {
uni.$u.api = { ...uni.$u.api } || {};
// 登录
// uni.$u.api.signin = params => login.index(params);
uni.$u.api.signin = params => uni.$u.http.post(`${tall}/users/signin`, params); // 登录
uni.$u.api.signin = params => uni.$u.http.post(`${tall}/users/signin`, params);
// 注册
// uni.$u.api.signup = params => uni.$u.http.post(`${tall}/users/signup`, params);
// 获取图片验证码
uni.$u.api.getImageCode = () => uni.$u.get(`${tall}/users/code`);
// 获取短信验证码

5
common/js/config.js

@ -4,6 +4,11 @@ var config = {
msgUrl: 'wss://test.tall.wiki/websocket/message/v4.0/ws',
projectPath: 'https://test.tall.wiki/tall-project',
baseUrlNew: 'http://101.201.226.163',
apiUrlNew: 'http://101.201.226.163/gateway',
msgUrlNew: 'wss://101.201.226.163/websocket/message/v4.0/ws',
projectPathNew: 'https://101.201.226.163/tall-project',
// baseUrl: 'https://www.tall.wiki',
// apiUrl: 'https://www.tall.wiki/gateway',
// msgUrl: 'wss://www.tall.wiki/websocket/message/v4.0/ws';

70
common/styles/tailwind.scss

@ -2199,6 +2199,9 @@
margin-left: -1px;
}
.border-none{
border-style: none;
}
.box-border {
box-sizing: border-box;
}
@ -2215,7 +2218,12 @@
--tw-border-opacity: 1;
border-color: rgba(209, 213, 219, var(--tw-border-opacity));
}
.border{
border-width: 1px;
}
.border-solid{
border-style: solid;
}
.block {
display: block;
}
@ -2696,7 +2704,12 @@
.overflow-hidden {
overflow: hidden;
}
.visible{
visibility: visible;
}
.invisible{
visibility: hidden;
}
.overflow-visible {
overflow: visible;
}
@ -4336,9 +4349,21 @@
height: 0.75rem;
}
.h5{
height: 1.25rem;
}
.h-10{
height: 2.5rem;
}
.h-full {
height: 100%;
}
.leading-10{
line-height: 2.5rem;
}
.bg-gray-50 {
--tw-bg-opacity: 1;
background-color: rgba(249, 250, 251, var(--tw-bg-opacity));
@ -4367,7 +4392,10 @@
}
.h-12 {
height: 3rem;
height: 3.15rem;
}
.h-8{
height: 2.2rem;
}
.bg-white {
--tw-bg-opacity: 1;
@ -4465,6 +4493,10 @@
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.rounded-md{
border-radius: 0.375rem;
}
.shadow-md {
--tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
@ -4494,3 +4526,35 @@
--tw-shadow: 0 0 #0000;
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.bg-red-500{
--tw-bg-opacity: 1;
background-color: rgba(239, 68, 68, var(--tw-bg-opacity));
}
.bg-yellow-500{
--tw-bg-opacity: 1;
background-color: rgba(245, 158, 11, var(--tw-bg-opacity));
}
.leading-12{
line-height: 3.15rem;
}
.rounded-w-12{
border-radius: 1.5rem;
}
.bg-opacity-100{
--tw-bg-opacity: 1;
}
.bg-grey{
background-color: rgba(0,0,0,0.5);
}
.rounded-md{
border-radius: 0.375rem;
}
.border-t{
border-top-width: 1px;
}
.border-gray-200{
--tw-border-opacity: 1;
border-color: rgba(229, 231, 235, var(--tw-border-opacity));
}

23
common/styles/theme/default.scss

@ -1,10 +1,29 @@
// 默认主题文件
.theme-default {
background-color: #F3F3F3;
background-color: #007aff;
// color: #fff;
.u-card {
font-size: 24px !important;
color: #0f0;
font-size: 16px !important;
background-color: #F3F3F3 !important;
.deliverHead{
align-items: center;
}
.btns u-button{
margin: 0 !important;
}
.active{
background-color: #2979FF;
color: #FFFFFF;
}
.mask{
position:absolute;
top: 0;
left:0;
width: 100%;
height: 100%;
z-index: 100;
}
}
.u-navbar {
background-color: #007aff !important;

4
components/Globals/Globals.vue

@ -3,7 +3,8 @@
<u-card @click="openCard" :show-foot="false" :show-head="false" :style="{ 'max-height': globalsHeight + 'px' }" border-radius="25" margin="0" class="global-container">
<template v-slot:body>
<scroll-view :scrollY="true" :style="{ 'max-height': globalsHeight - 30 + 'px' }">
<skeleton :banner="false" :loading="showGlobalSkeleton" :row="3" animate class="u-line-2 skeleton"></skeleton>
<!-- <skeleton :banner="false" :loading="!globals.length" :row="3" animate class="u-line-2 skeleton"></skeleton> -->
<view class="grid gap-2">
<view v-for="item in globals" :key="item.id">
<template v-if="item.plugins && item.plugins.length">
@ -59,6 +60,7 @@ function openCard() {
store.commit('task/setShrink', false);
}
}
</script>
<style scoped lang="scss">

19
components/ModalBox/ModalBox.vue

@ -0,0 +1,19 @@
<template>
<!-- 标题部分 -->
<view>
ssss
</view>
<!-- 输入框 -->
<view>
</view>
<!-- 按钮 -->
</template>
<script>
</script>
<style>
</style>

343
components/PrettyExchange/PrettyExchange.vue

@ -22,8 +22,10 @@
@touchend="stops($event, index)"
@touchmove.stop.prevent="move"
@touchstart="start($event, index)"
class="cu-item flex-col" v-for="(item, index) in data.itemList"
class="cu-item flex-col"
v-for="(item, index) in data.itemList"
>
<view class="border-100 bg-blue-500" v-if="item.showTopBorder"></view>
<!-- 内容区 -->
@ -57,14 +59,17 @@
<!-- 子项目 -->
<view class="ml-8" v-if="item.show">
<view :id="'cu-' + index + '-' + subIndex" :key="subIndex"
<view
:id="'cu-' + index + '-' + subIndex"
:key="subIndex"
@touchend.stop.prevent="stops($event, index + '-' + subIndex, item.sonProjectList.length)"
@touchmove.stop.prevent="move($event, item.sonProjectList.length)"
@touchstart.stop.prevent="start($event, index + '-' + subIndex)"
class="cu-item flex-col" v-for="(subItem, subIndex) in item.sonProjectList">
@touchstart.stop.prevent="start($event, index + '-' + subIndex)" class="cu-item flex-col"
v-for="(subItem, subIndex) in item.sonProjectList"
>
<view class="flex items-center justify-between p-3 w-full">
<u-icon class="mover" name="https://www.tall.wiki/staticrec/drag.svg" size="48">
</u-icon>
<u-icon class="mover" name="https://www.tall.wiki/staticrec/drag.svg" size="48"></u-icon>
<view class="flex-1 px-3">
<view class="flex items-center">
@ -102,8 +107,8 @@
<!-- 移动悬浮 begin -->
<view v-if="data.showMoveImage">
<view :style="{ left: moveLeft + 'px', top: moveTop + 'px' }" class="cu-item absolute">
<ProjectItem class="w-full" :item="moveItem" />
<view :style="{ left: data.moveLeft + 'px', top: data.moveTop + 'px' }" class="cu-item absolute">
<ProjectItem class="w-full" :item="data.moveItem" />
</view>
</view>
<!-- 移动悬浮 end -->
@ -114,109 +119,116 @@
</template>
<script setup>
import { ref, onMounted, watch, computed } from 'vue';
import { reactive, onMounted, watch, computed } from 'vue';
import ProjectItem from '@/components/Projects/ProjectItem.vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
const store = useStore();
const projects = computed(() => store.state.project.projects);
const data = ref({
itemTop: 0,
itemLeft: 0,
const data = reactive({
// itemTop: 0,
// itemLeft: 0,
itemHeight: 0, //
subItemHeight: 0, //
itemWidth: 0, //
subItemHeight: 0, //
showMoveImage: false,
moveItem: '',
moveLeft: 0,
moveTop: 0,
moveItem: '', //
moveLeft: 0, //
moveTop: 0, //
deltaLeft: 0,
deltaTop: 0,
beginleft: 0,
begintop: 0,
itemList: [],
setSubItem: false,
changeEvent: false,
beginleft: 0, //
begintop: 0, //
itemList: [], //
setSubItem: false, //
changeEvent: false, //
showMenu: false,
tips: {
text: '',
color: '#909399',
fontSize: 28,
},
tips: { text: '', color: '#909399', fontSize: 28, },
projectId: 0,
menuList: [{ text: '复制' }, { text: '编辑' }, { text: '删除' }, { text: '置顶' }, { text: '排序' }],
// show: false,
border: 'border border-blue-500 shadow rounded-md',
showBorder: false,
// border: 'border border-blue-500 shadow rounded-md',
showBorder: false, //
showItemIndex: undefined,
});
const emit = defineEmits(['changeHeight', 'change']);
//
watch(projects, (val) => {
data.value.itemList = val;
data.value.itemList.forEach(item => {
item.showBorder = false;
item.showSubBorder = false;
item.showTopBorder = false;
data.itemList = val;
data.itemList.forEach(item => {
item.showBorder = false; //
item.showSubBorder = false; //
item.showTopBorder = false; //
});
})
onMounted(() => {
data.value.itemList = projects.value;
data.value.itemList.forEach(item => {
item.showBorder = false;
item.showSubBorder = false;
item.showTopBorder = false;
data.itemList = projects.value;
data.itemList.forEach(item => {
item.showBorder = false; //
item.showSubBorder = false; //
item.showTopBorder = false; //
});
});
//
function openSubProject(length, index) {
setProjectItemShow({ index, show: data.value.itemList[index].show ? false : true });
store.commit('project/setProjectItemShow', { index, show: data.itemList[index].show ? false : true });
if (length && index) {
this.$emit('changeHeight', length, index);
emit('changeHeight', length, index);
}
data.value.showItemIndex = index;
data.showItemIndex = index;
}
//
function getDate() {
const query = uni.createSelectorQuery().in(this);
query.select(`#cu-0`).boundingClientRect(res => {
console.log('data: ', res);
data.value.begintop = res.top;
data.value.beginleft = res.left;
const query = uni.createSelectorQuery().select(`#cu-0`).fields({
id: true,
dataset: true,
rect: true,
size: true
}, res => {
data.begintop = res.top;
data.beginleft = res.left;
}).exec();
}
function setData(flag, projectId, tips) {
data.value.showMenu = flag;
data.value.projectId = projectId;
data.value.tips = tips;
data.showMenu = flag;
data.projectId = projectId;
data.tips = tips;
}
function chooseAction(e) {
let obj = { index: e, projectId: data.value.projectId };
// this.$emit('chooseAction', data);
let obj = {
index: e,
projectId: data.projectId
};
// emit('chooseAction', data);
actionFun(obj);
}
//
function actionFun(obj) {
let action = data.value.menuList[obj.index].text;
let action = data.menuList[obj.index].text;
if (action === '排序') {
data.value.changeEvent = true;
data.changeEvent = true;
uni.$ui.showToast('请移动进行排序');
}
if (action === '删除') {
data.value.changeEvent = false;
data.changeEvent = false;
delProject(obj.projectId);
}
if (data.value.showItemIndex !== undefined) {
setProjectItemShow({ index: data.value.showItemIndex, show: true });
if (data.showItemIndex !== undefined) {
store.commit('project/setProjectItemShow', {
index: data.showItemIndex,
show: true
});
}
}
@ -225,76 +237,89 @@
}
function start(e, index) {
console.log('开始', e);
console.log('开始');
setTimeout(() => {
getDate();
}, 300);
if (isNumber(index)) {
data.value.setSubItem = false;
const query = uni.createSelectorQuery().in(this);
console.log('2222', query)
query.select(`#cu-${index}`).boundingClientRect(res => {
data.value.moveTop = res.top;
data.value.moveLeft = res.left;
data.value.moveItem = data.value.itemList[index];
data.value.itemWidth = res.width;
data.value.itemHeight = res.height;
if (isNumber(index)) { //
data.setSubItem = false;
const query = uni.createSelectorQuery().select(`#cu-${index}`).fields({
id: true,
dataset: true,
rect: true,
size: true
}, res => {
data.moveTop = res.top;
data.moveLeft = res.left;
data.moveItem = data.itemList[index];
data.itemWidth = res.width;
data.itemHeight = res.height;
}).exec();
} else {
} else { //
let arr = index.split('-');
data.value.setSubItem = true;
const query = uni.createSelectorQuery().in(this);
query.select(`#cu-${arr[0] - 0}`).boundingClientRect(res => {
data.value.itemHeight = res.height;
data.setSubItem = true;
const query = uni.createSelectorQuery();
query.select(`#cu-${arr[0] - 0}`).fields({
id: true,
dataset: true,
rect: true,
size: true
}, res => {
data.itemHeight = res.height;
}).exec();
query.select(`#cu-${index}`).boundingClientRect(res => {
data.value.moveTop = res.top;
data.value.moveLeft = res.left;
data.value.moveItem = data.value.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
data.value.itemWidth = res.width;
data.value.subItemHeight = res.height;
query.select(`#cu-${index}`).fields({
id: true,
dataset: true,
rect: true,
size: true
}, res => {
data.moveTop = res.top;
data.moveLeft = res.left;
data.moveItem = data.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
data.itemWidth = res.width;
data.subItemHeight = res.height;
}).exec();
}
}
function move(e, length) {
console.log('移动');
data.value.showMoveImage = true; //
data.showMoveImage = true; //
const touch = e.touches[0];
if (data.value.deltaLeft == 0) {
if (data.deltaLeft == 0) {
//
data.value.deltaLeft = touch.pageX - data.value.moveLeft;
data.value.deltaTop = touch.pageY - data.value.moveTop;
data.deltaLeft = touch.pageX - data.moveLeft;
data.deltaTop = touch.pageY - data.moveTop;
}
data.value.moveLeft = touch.pageX - data.value.deltaLeft;
data.value.moveTop = touch.pageY - data.value.deltaTop;
data.moveLeft = touch.pageX - data.deltaLeft;
data.moveTop = touch.pageY - data.deltaTop;
let lastIndex = (lastIndex = findOverIndex(touch.pageY, length));
console.log('111111', lastIndex);
let lastIndex = findOverIndex(touch.pageY, length);
// 线
for (let i = 0; i < data.value.itemList.length; i++) {
if (data.value.moveLeft > 35) {
data.value.itemList[i].showBorder = false;
data.value.itemList[i].showTopBorder = false;
for (let i = 0; i < data.itemList.length; i++) {
if (data.moveLeft > 35) {
data.itemList[i].showBorder = false;
data.itemList[i].showTopBorder = false;
if (i === lastIndex) {
data.value.itemList[i].showSubBorder = true;
data.itemList[i].showSubBorder = true;
} else {
data.value.itemList[i].showSubBorder = false;
data.itemList[i].showSubBorder = false;
}
} else {
if (lastIndex === -1) {
data.value.itemList[0].showTopBorder = true;
data.value.itemList[i].showSubBorder = false;
data.value.itemList[i].showBorder = false;
data.itemList[0].showTopBorder = true;
data.itemList[i].showSubBorder = false;
data.itemList[i].showBorder = false;
} else {
data.value.itemList[i].showSubBorder = false;
data.value.itemList[i].showTopBorder = false;
data.itemList[i].showSubBorder = false;
data.itemList[i].showTopBorder = false;
if (i === lastIndex) {
data.value.itemList[i].showBorder = true;
data.itemList[i].showBorder = true;
} else {
data.value.itemList[i].showBorder = false;
data.itemList[i].showBorder = false;
}
}
}
@ -303,98 +328,98 @@
function stops(e, index, length) {
console.log('结束');
const touch = e.mp.changedTouches[0];
let lastIndex = (lastIndex = findOverIndex(touch.pageY, length));
const touch = e.changedTouches[0];
let lastIndex = findOverIndex(touch.pageY, length);
//
for (let i = 0; i < data.value.itemList.length; i++) {
for (let i = 0; i < data.itemList.length; i++) {
//
if (data.value.itemList[i].showTopBorder) {
if (data.itemList[i].showTopBorder) {
if (isNumber(index)) {
let Value = data.value.itemList[index];
data.value.itemList.unshift(Value);
data.value.itemList.splice(index + 1, 1);
let Value = data.itemList[index];
data.itemList.unshift(Value);
data.itemList.splice(index + 1, 1);
} else {
let arr = index.split('-');
let Value = data.value.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
data.value.itemList.unshift(Value);
data.value.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1);
let Value = data.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
data.itemList.unshift(Value);
data.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1);
const options = {
id: Value.id,
parentId: 0,
};
this.$emit('change', options);
emit('change', options);
}
//
clearSet(i);
this.$emit('change', data.value.itemList);
emit('change', data.itemList);
return;
}
//
if (data.value.itemList[i].showBorder) {
if (data.itemList[i].showBorder) {
if (isNumber(index)) {
let Value = data.value.itemList[index];
data.value.itemList.splice(i + 1, 0, Value);
let Value = data.itemList[index];
data.itemList.splice(i + 1, 0, Value);
if (i < index) {
data.value.itemList.splice(index + 1, 1);
data.itemList.splice(index + 1, 1);
} else {
data.value.itemList.splice(index, 1);
data.itemList.splice(index, 1);
}
} else {
let arr = index.split('-');
let Value = data.value.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
data.value.itemList.splice(i + 1, 0, Value);
data.value.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1);
let Value = data.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
data.itemList.splice(i + 1, 0, Value);
data.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1);
const options = {
id: Value.id,
parentId: 0,
};
this.$emit('change', options);
emit('change', options);
}
//
clearSet(i);
this.$emit('change', data.value.itemList);
emit('change', data.itemList);
return;
}
//
if (data.value.itemList[i].showSubBorder) {
if (data.itemList[i].showSubBorder) {
if (isNumber(index)) {
let Value = data.value.itemList[index];
if (data.value.itemList[lastIndex - 1].sonProjectList && data.value.itemList[lastIndex - 1].sonProjectList.length) {
data.value.itemList[lastIndex - 1].sonProjectList.push(Value);
let Value = data.itemList[index];
if (data.itemList[lastIndex - 1].sonProjectList && data.itemList[lastIndex - 1].sonProjectList.length) {
data.itemList[lastIndex - 1].sonProjectList.push(Value);
} else {
data.value.itemList[lastIndex].sonProjectList = [Value];
data.itemList[lastIndex].sonProjectList = [Value];
}
data.value.itemList.splice(index, 1);
data.itemList.splice(index, 1);
//
clearSet(i);
const options = {
id: Value.id,
parentId: data.value.itemList[lastIndex - 1].id,
parentId: data.itemList[lastIndex - 1].id,
};
this.$emit('change', options);
emit('change', options);
} else {
let arr = index.split('-');
let Value = data.value.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
if (data.value.itemList[lastIndex].sonProjectList && data.value.itemList[lastIndex].sonProjectList.length) {
data.value.itemList[lastIndex].sonProjectList.push(Value);
let Value = data.itemList[arr[0] - 0].sonProjectList[arr[1] - 0];
if (data.itemList[lastIndex].sonProjectList && data.itemList[lastIndex].sonProjectList.length) {
data.itemList[lastIndex].sonProjectList.push(Value);
} else {
data.value.itemList[lastIndex].sonProjectList = [Value];
data.itemList[lastIndex].sonProjectList = [Value];
}
data.value.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1);
data.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1);
//
clearSet(i);
const options = {
id: Value.id,
parentId: data.value.itemList[lastIndex].id,
parentId: data.itemList[lastIndex].id,
};
this.$emit('change', options);
emit('change', options);
const options1 = {
id: Value.id,
parentId: 0,
};
this.$emit('change', options1);
emit('change', options1);
}
return;
}
@ -403,34 +428,34 @@
//
function clearSet(i) {
data.value.itemList[i].showBorder = false;
data.value.itemList[i].showSubBorder = false;
data.value.itemList[i].showTopBorder = false;
data.value.deltaLeft == 0;
data.value.showMoveImage = false;
data.value.setSubItem = false;
data.value.changeEvent = false;
data.value.showItemIndex = undefined;
data.itemList[i].showBorder = false;
data.itemList[i].showSubBorder = false;
data.itemList[i].showTopBorder = false;
data.deltaLeft == 0;
data.showMoveImage = false;
data.setSubItem = false;
data.changeEvent = false;
data.showItemIndex = undefined;
}
//
function findOverIndex(posY) {
//
let leng = data.value.itemList.length * data.value.itemHeight; //
if (posY < data.value.begintop) {
let leng = data.itemList.length * data.itemHeight; //
if (posY < data.begintop) {
return -1;
}
for (var i = 0; i < data.value.itemList.length; i++) {
let begin = data.value.itemHeight * i + data.value.begintop;
let end = data.value.itemHeight * i + data.value.begintop + data.value.itemHeight;
for (var i = 0; i < data.itemList.length; i++) {
let begin = data.itemHeight * i + data.begintop;
let end = data.itemHeight * i + data.begintop + data.itemHeight;
if (begin <= posY && end >= posY) {
return i;
}
}
if (posY > leng) {
//
return data.value.itemList.length - 1;
} else if (posY < data.value.begintop) {
return data.itemList.length - 1;
} else if (posY < data.begintop) {
return 0;
}
}
@ -441,18 +466,20 @@
title: '',
content: '是否删除项目?',
showCancel: true,
success: async ({ confirm }) => {
success: async ({
confirm
}) => {
if (confirm) {
await this.$u.api.delProject(id);
await uni.$u.api.delProject(id);
let flag_index = 0;
data.value.itemList.forEach((item, index) => {
data.itemList.forEach((item, index) => {
if (item.id == id) {
flag_index = index;
}
});
data.value.itemList.splice(flag_index, 1);
setProjects(data.value.itemList);
data.itemList.splice(flag_index, 1);
store.commit('project/setProjects', data.itemList);
}
},
});

17
components/Projects/ProjectItem.vue

@ -12,16 +12,16 @@
</view>
<view class="flex items-center text-xs text-gray-400">
<view class="pr-2">{{ dayjs(item.startTime).format('MM-DD HH:mm') }}</view>
<view class="pr-2">{{ dayjs(+item.startTime).format('MM-DD HH:mm') }}</view>
<view class="pl-2">{{ dayjs(item.endTime).format('MM-DD HH:mm') }}</view>
<view class="pl-2">{{ dayjs(+item.endTime).format('MM-DD HH:mm') }}</view>
</view>
</view>
<!-- 箭头 -->
<view v-if="item.sonProjectList && item.sonProjectList.length">
<u-icon @click="$emit('openSubProject', item.sonProjectList.length, index)" class="text-gray-400" name="arrow-up" size="14px" v-if="item.show"></u-icon>
<u-icon @click="$emit('openSubProject', item.sonProjectList.length, index)" class="text-gray-400" name="arrow-down" size="14px" v-else></u-icon>
<u-icon @click="emit('openSubProject', item.sonProjectList.length, index)" class="text-gray-400" name="arrow-up" size="14px" v-if="item.show"></u-icon>
<u-icon @click="emit('openSubProject', item.sonProjectList.length, index)" class="text-gray-400" name="arrow-down" size="14px" v-else></u-icon>
</view>
<u-icon @click="openProject(item)" class="text-gray-400" name="arrow-right" size="14px" v-else></u-icon>
</view>
@ -63,7 +63,7 @@
</template>
<script setup>
import { ref, computed } from 'vue';
import { reactive, computed } from 'vue';
import dayjs from 'dayjs';
import { useStore } from 'vuex';
import config from '@/common/js/config.js';
@ -82,12 +82,12 @@ defineProps({
// default: () => [],
// },
});
const emit = defineEmits(['setData']);
const emit = defineEmits(['setData', 'openSubProject']);
const store = useStore();
const userId = computed(() => store.getters['user/userId']);
const data = ref({
const data = reactive({
showMenu: false,
tips: {
text: '',
@ -102,7 +102,7 @@ const data = ref({
//
function openProject(project) {
const gateway = config.apiUrl;
const gateway = config.apiUrlNew;
const url = `${gateway}/defaultwbs`;
const { name, id } = project;
uni.navigateTo({ url: `/pages/project/project?u=${userId.value}&p=${id}&pname=${name}&url=${encodeURIComponent(url)}` });
@ -117,7 +117,6 @@ function openMenu(project) {
data.tips.text = project.name;
emit('setData', data.showMenu, data.projectId, data.tips);
// this.$emit('setData', data.showMenu, data.projectId, data.tips);
}
</script>

6
components/Projects/Projects.vue

@ -5,6 +5,8 @@
</template>
<script setup>
const emit = defineEmits(['getProjects']);
function change(options) {
if (options instanceof Array) {
let projectIdList = [];
@ -32,7 +34,7 @@
console.log('error: ', error);
uni.$ui.showToast(error.msg || '排序修改失败');
}
this.$emit('getProjects');
emit('getProjects');
}
/**
@ -49,7 +51,7 @@
console.error('error: ', error);
uni.$ui.showToast(error.msg || '排序修改失败');
}
this.$emit('getProjects');
emit('getProjects');
}
</script>

91
components/Reviewer/Reviewer.vue

@ -0,0 +1,91 @@
<template>
<view class="deliverFoot border border-solid border-gray-300 rounded-md mt-3 p-2">
<view class="top flex justify-between">
<view class="mr-3">
审核人
</view>
<!-- 展示选择的审核人 -->
<view class="flex approver item-center truncate justify-end flex-1 text-sm" v-show="isUicon">
<view v-for="item in computedDelivers">
<view v-show="item.checked" class="mx-1">
{{item.name}}
</view>
</view>
</view>
<!-- 点击更换图标 -->
<view>
<u-icon v-if="isUicon" name="arrow-down" @click="changeIcon"></u-icon>
<u-icon v-else="isUicon" name="arrow-up" @click="changeIcon"></u-icon>
</view>
</view>
<!-- 隐藏的审核人选项 -->
<view v-show="!isUicon" class="foot mt-2 flex flex-wrap">
<u-button
v-for="item in delivers"
size="mini" class="my-1 mx-2"
@click="item.checked = !item.checked"
:class="item.checked ? 'active' : '' "
>
{{item.name}}
</u-button>
</view>
</view>
</template>
<script setup>
import {ref , reactive , computed }from 'vue'
//
let isUicon = ref('true')
//
const delivers = reactive([
{
checked:true,
name:'冯教授'
},
{
checked:false,
name:'陈历珺'
},
{
checked:false,
name:'张野'
},
{
checked:false,
name:'宋瑞芳'
},
{
checked:false,
name:'张斌'
},
{
checked:false,
name:'孙方圆'
}
])
//
const computedDelivers = computed(()=>{
let arr = [];
delivers.forEach((item)=>{
if(item.checked){
arr.push(item)
}
if(arr.length>3){
arr = arr.splice(0,3)
arr[3] = {checked:true,name:'...'}
}
})
return arr
})
//
function changeIcon(){
isUicon.value = !isUicon.value
}
</script>
<style lang="scss">
</style>

24
hooks/user/userMixin.js

@ -1,6 +1,5 @@
import { ref, computed, reactive } from 'vue';
import { useStore } from 'vuex';
import { onReady } from '@dcloudio/uni-app';
import clipboard from "@/common/js/dc-clipboard/clipboard.js";
import Config from '@/common/js/config.js'
@ -16,7 +15,7 @@ export default function userMixin() {
{
validator: (rule, value, callback) => {
// 调用uView自带的js验证规则,详见:https://www.uviewui.com/js/test.html
return this.$u.test.mobile(value);
return uni.$u.test.mobile(value);
},
message: '手机号码不正确',
// 触发器可以同时用blur和change,二者之间用英文逗号隔开
@ -88,12 +87,12 @@ export default function userMixin() {
// const showPaste = ref(false);
const dataObj = reactive({
showInterval: false,
interval: 120,
interval: 60,
showPaste: false
})
});
//有图片验证码的值
function hasvalue(form) {
function hasvalue(form, renderData) {
if(form.smsCode || form.showPaste) return
if (!verifyPhone(form.phone)) {
uni.$ui.showToast('请输入正确的手机号');
@ -103,26 +102,29 @@ export default function userMixin() {
uni.$ui.showToast('请输入图形验证码');
return;
}
getCode(form);
if (!dataObj.showInterval) {
getCode(form, renderData);
}
}
// 获取验证码
async function getCode(form) {
async function getCode(form, renderData) {
try {
if (!form.verificationCodeId || !form.verificationCodeValue) {
if (!renderData.verificationCodeId || !form.verificationCodeValue) {
uni.$ui.showToast('缺少图形验证码参数');
return;
}
const params = {
phone: form.phone,
verificationCodeId: form.verificationCodeId,
verificationCodeId: renderData.verificationCodeId,
verificationCodeValue: form.verificationCodeValue,
};
const date = await store.dispatch('user/sendCode', params);
getCodeInterval();
dataObj.showPaste = true;
} catch (err) {
getImageCode();
dataObj.showPaste = false;
throw err;
}
}
@ -135,7 +137,7 @@ export default function userMixin() {
clearInterval(codeTimer.value);
codeTimer.value = null;
dataObj.showInterval = false;
dataObj.interval = 120;
dataObj.interval = 60;
return;
}
dataObj.interval = dataObj.interval - 1;

8
manifest.json

@ -77,6 +77,9 @@
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
},
"splashscreen" : {
"androidStyle" : "common"
}
}
},
@ -102,5 +105,8 @@
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
"vueVersion" : "3",
"h5" : {
"title" : "时物链"
}
}

28
pages.json

@ -3,7 +3,8 @@
{
"path": "pages/index/index",
"style": {
"navigationBarText": "TALL"
"navigationBarText": "TALL",
"navigationStyle": "custom"
}
},
{
@ -28,6 +29,31 @@
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
},
//
{
"path": "pages/user/rigister",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
},
//
{
"path": "pages/user/agreement",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
}
,{
"path" : "pages/submitList/submitList",
"style" :
{
"navigationStyle": "historty",
"navigationBarTitleText": "历史交付物"
}
}
],
"globalStyle": {

121
pages/index/index.vue

@ -1,13 +1,15 @@
<template>
<!-- <view class="flex flex-col h-full bg-gray-50" @click="openAuth"> -->
<view class="flex flex-col h-full bg-gray-50">
<view class="relative" @touchmove="onMove">
<view class="relative">
<!-- <view class="relative" @touchmove="onMove"> -->
<!-- 日历 -->
<Calendar @selected-change="onDateChange" :show-back="true" ref="calendar" @handleFindPoint="handleFindPoint" />
<!-- 上传 导入wbs -->
<Upload @success="onUploadSuccess" @error="onUploadError" />
</view>
<u-button @click="toLogin">登录</u-button>
<u-button class="mt-4" @click="toLogin">登录</u-button>
<!-- 项目列表 -->
<Projects @getProjects="getProjects" class="flex-1 overflow-y-auto" />
@ -17,31 +19,33 @@
</template>
<script setup>
import { reactive, computed, watchEffect, ref } from 'vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
import { reactive, computed, watchEffect, ref } from 'vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
const store = useStore();
const token = computed(() => store.state.user.token);
const uTips = ref(null);
const store = useStore();
const token = computed(() => store.state.user.token);
const uTips = ref(null);
const data = reactive({
const data = reactive({
calendar: null,
days: [],
});
// days: [],
});
// token
watchEffect(() => {
if (!token.value) return;
if (token.value) {
getProjects();
handleFindPoint();
}
});
//
function getProjects(start = dayjs().startOf('day').valueOf(), end = dayjs().endOf('day').valueOf()) {
// const data = await this.$u.api.getProjects(start, end);
// token
// watchEffect(() => {
// if (!token.value) return;
// if (token.value) {
// getProjects();
// handleFindPoint();
// }
// });
//
function getProjects(start = dayjs().startOf('day').valueOf(), end = dayjs().endOf('day').valueOf()) {
uni.$catchReq.getProjects(start, end, (err, data) => {
if (err) {
console.error('err: ', err);
@ -52,9 +56,9 @@ function getProjects(start = dayjs().startOf('day').valueOf(), end = dayjs().end
store.commit('project/setProjects', data);
}
});
}
}
async function handleFindPoint(start, end) {
async function handleFindPoint(start, end) {
try {
const startTime = start || dayjs().startOf('month').valueOf();
const endTime = end || dayjs().endOf('month').valueOf();
@ -63,79 +67,82 @@ async function handleFindPoint(start, end) {
} catch (error) {
console.log('error: ', error);
}
}
}
//
const onDateChange = event => {
//
const onDateChange = event => {
const day = dayjs(event.fullDate);
const start = day.startOf('date').valueOf();
const end = day.endOf('date').valueOf();
getProjects(start, end);
};
};
//
const onUploadSuccess = () => {
//
const onUploadSuccess = () => {
uni.$ui.showToast('导入成功,即将打开新项目', 3000);
// uTips.show({
// title: '',
// type: 'success',
// duration: '3000',
// });
};
};
//
const onUploadError = error => {
//
const onUploadError = error => {
uni.$ui.showToast('导入失败', 6000);
// uTips.show({
// title: error || '',
// type: 'error',
// duration: '6000',
// });
};
// /
function onMove(event) {
const y = event.changedTouches[0].pageY;
if (y - prevY > 0) {
// weekMode=true weekMode=false
data.value.calendar.weekMode && (data.value.calendar.weekMode = false);
} else if (y - prevY < 0) {
// weekMode=false weekMode=true
!data.value.calendar.weekMode && (data.value.calendar.weekMode = true);
};
// /
// function onMove(event) {
// const y = event.changedTouches[0].pageY;
// const prevY = 0;
// if (y - prevY > 0) {
// // weekMode=true weekMode=false
// data.calendar.weekMode && (data.calendar.weekMode = false);
// } else if (y - prevY < 0) {
// // weekMode=false weekMode=true
// !data.calendar.weekMode && (data.calendar.weekMode = true);
// }
// prevY = y;
// data.calendar.initDate();
// }
function toLogin() {
uni.navigateTo({
url: '/pages/user/login'
})
}
prevY = y;
data.value.calendar.initDate();
}
function toLogin() {
uni.navigateTo({ url: '/pages/user/accountLogin' });
}
</script>
<style>
.content {
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
.logo {
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
}
.text-area {
.text-area {
display: flex;
justify-content: center;
}
}
.title {
.title {
font-size: 36rpx;
color: #8f8f94;
}
}
</style>

26
pages/submitlist/submitlist.vue

@ -0,0 +1,26 @@
<template>
<theme class="h-full w-full pt-1">
<view class="bg-white m-5 rounded-md p-3">
<view class="flex justify-between text-gray-400 mb-2">
<view>插件名</view> <view>提交时间</view>
</view>
<view class="text-blue-400 mb-2">
链接
</view>
<view class="mb-2">审核人</view>
</view>
</theme>
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

10
pages/user/accountLogin.vue

@ -62,8 +62,14 @@
async function login() {
uni.$ui.showLoading();
try {
// #ifdef H5
const client = 0;
// #endif
// #ifdef APP-PLUS
const client = 1;
// #endif
const params = reactive({
client: 1,
client: client,
data: {
identifier: form.account,
credential: form.password,
@ -75,7 +81,7 @@
store.commit('user/setToken', res.token);
store.commit('user/setUser', res);
uni.$storage.setStorageSync('anyringToken', res.token || '');
uni.$storage.setStorageSync('user', JSON.stringify(res));
uni.$storage.setStorageSync('user', JSON.stringify(res) || '');
uni.$ui.hideLoading();

18
pages/user/agreement.vue

@ -0,0 +1,18 @@
<template>
<view>
<web-view class="webview" src="https://www.yuque.com/docs/share/2de362e1-33fb-460a-92ca-5e8ef57f6d59?# 《时物链条用户协议》"></web-view>
<!-- <u-modal title="时物链条用户协议" v-model="showAgreement" show-cancel-button @confirm="$emit('confirm')" @cancel="$emit('cancel')">
<iframe
src="https://www.yuque.com/docs/share/2de362e1-33fb-460a-92ca-5e8ef57f6d59?# 《时物链条用户协议》"
frameborder="0"
scrolling="no"
style="width: 100%;height: 100%"
></iframe>
</u-modal> -->
</view>
</template>
<script>
</script>
<style></style>

80
pages/user/login.vue

@ -1,17 +1,17 @@
<template>
<view class="u-p-l-50 u-p-r-50 u-p-t-30">
<u-form :model="form" ref="loginForm" :error-type="['message']">
<u-form-item label="手机号码" prop="phone" label-width="150">
<u-form :model="form" ref="phoneLoginForm" :error-type="['message']">
<u-form-item label="手机号码" prop="phone" label-width="160">
<u-input placeholder="请输入手机号" v-model="form.phone" type="number"></u-input>
</u-form-item>
<u-form-item label="图形验证码" prop="verificationCodeValue" label-width="150">
<u-form-item label="图形验证码" prop="verificationCodeValue" label-width="160">
<u-input placeholder="请输入计算结果" v-model="form.verificationCodeValue" type="number"></u-input>
<image slot="right" :src="imageBase64" mode="aspectFit" class="code-image" @click="getImageCode"></image>
<image slot="right" :src="renderData.imageBase64" mode="aspectFit" class="code-image" @click="getImageCode"></image>
</u-form-item>
<u-form-item label="验证码" prop="smsCode" label-width="150">
<u-input @focus="mixinInit.hasvalue(form)" placeholder="请输入验证码" v-model="form.smsCode" type="text"></u-input>
<u-form-item label="验证码" prop="smsCode" label-width="160">
<u-input @focus="mixinInit.hasvalue(form, renderData)" placeholder="请输入验证码" v-model="form.smsCode" type="text"></u-input>
<u-button slot="right" type="primary" size="mini" v-show="mixinInit.dataObj.showPaste" @click="mixinInit.setCode" class="u-m-r-20">粘贴</u-button>
<u-button slot="right" size="mini" v-if="mixinInit.dataObj.showInterval">{{ mixinInit.dataObj.interval }}</u-button>
</u-form-item>
@ -23,7 +23,7 @@
</u-form>
<view class="u-m-t-50">
<u-button @click="submit" type="primary">立即登录</u-button>
<u-button @click="submitLogin" type="primary">立即登录</u-button>
</view>
<view class="flex justify-between">
@ -43,56 +43,53 @@
<script setup>
import { ref, computed, reactive } from 'vue';
import { useStore } from 'vuex';
import { onLoad, onReady } from '@dcloudio/uni-app';
import { onReady } from '@dcloudio/uni-app';
import userMixin from '@/hooks/user/userMixin'
const store = useStore();
const mixinInit = userMixin();
const loginForm = ref(null);
const phoneLoginForm = ref(null);
const form = reactive({
phone: '',
verificationCodeId: '', // id
verificationCodeValue: '', //
smsCode: ''
});
const imageBase64 = ref(null); //
getImageCode();
const renderData = reactive({
verificationCodeId: '', // id
imageBase64: '' //
})
onReady(() => {
loginForm.value.setRules(mixinInit.rules);
phoneLoginForm.value.setRules(mixinInit.rules);
});
function submit() {
console.log('111111')
loginForm.value.validate(valid => {
console.log('22222', valid)
getImageCode(); //
//
const submitLogin = () => {
phoneLoginForm.value.validate(valid => {
if (valid) {
login()
}
});
}
//
async function getImageCode() {
uni.$ui.showLoading();
try {
const data = await uni.$u.api.getImageCode();
imageBase64.value = data.imageBase64 || '';
form.verificationCodeId = data.verificationCodeId || '';
uni.$ui.hideLoading();
} catch (error) {
uni.$ui.hideLoading();
uni.$ui.showToast(error);
}
}
/**
* 登录
*/
async function login() {
uni.$ui.showLoading();
try {
// #ifdef H5
const client = 0;
// #endif
// #ifdef APP-PLUS
const client = 1;
// #endif
const params = reactive({
client: 1,
client: client,
data: {
identifier: form.phone,
credential: form.smsCode,
@ -104,19 +101,34 @@
store.commit('user/setToken', res.token);
store.commit('user/setUser', res);
uni.$storage.setStorageSync('anyringToken', res.token || '');
uni.$storage.setStorageSync('user', JSON.stringify(res));
uni.$storage.setStorageSync('user', JSON.stringify(res) || '');
uni.$ui.hideLoading();
uni.navigateTo({
url: '/pages/index/index'
});
} catch (error) {
uni.$ui.hideLoading();
uni.$ui.showToast(error.msg);
}
}
//
async function getImageCode() {
uni.$ui.showLoading();
try {
const data = await uni.$u.api.getImageCode();
renderData.imageBase64 = data.imageBase64 || '';
renderData.verificationCodeId = data.verificationCodeId || '';
uni.$ui.hideLoading();
} catch (error) {
uni.$ui.hideLoading();
uni.$ui.showToast(error);
}
}
//
function openPage(url) {
uni.navigateTo({
url: url

153
pages/user/rigister.vue

@ -1,8 +1,159 @@
<template>
<view class="u-p-l-50 u-p-r-50 u-p-t-30">
<u-form :model="form" ref="signUpForm" :error-type="['message']">
<u-form-item label="手机号码" prop="phone" label-width="160">
<u-input placeholder="请输入手机号" v-model="form.phone" type="number"></u-input>
</u-form-item>
<u-form-item label="图形验证码" prop="verificationCodeValue" label-width="160">
<u-input placeholder="请输入计算结果" v-model="form.verificationCodeValue" type="number"></u-input>
<image slot="right" :src="renderData.imageBase64" mode="aspectFit" class="code-image" @click="getImageCode"></image>
</u-form-item>
<u-form-item label="验证码" prop="smsCode" label-width="160">
<u-input @focus="mixinInit.hasvalue(form, renderData)" placeholder="请输入验证码" v-model="form.smsCode" type="text"></u-input>
<u-button slot="right" type="primary" size="mini" v-show="mixinInit.dataObj.showPaste" @click="mixinInit.setCode" class="u-m-r-20">粘贴</u-button>
<u-button slot="right" size="mini" v-if="mixinInit.dataObj.showInterval">{{ mixinInit.dataObj.interval }}</u-button>
</u-form-item>
<u-form-item label="用户名" prop="account" label-width="160">
<u-input placeholder="请输入用户名" v-model="form.account" type="text"></u-input>
</u-form-item>
<u-form-item label="密码" prop="password" label-width="160">
<u-input :password-icon="true" type="password" v-model="form.password" placeholder="请输入密码"></u-input>
</u-form-item>
<view class="flex flex-nowrap">
<view class="flex-sub"></view>
<view class="u-m-t-30 u-font-12 text-gray-400" @click="openPage('/pages/user/forgetPassword')">忘记密码</view>
</view>
</u-form>
<view class="u-m-t-50">
<u-button @click="submit" type="primary">立即注册</u-button>
</view>
<view class="flex flex-direction u-m-t-30">
<view class="flex flex-nowrap u-m-b-20">
<u-checkbox v-model="renderData.checked" @change="changeChecked"></u-checkbox>
<view class="agreement-text">
已阅读并同意使用
<span class="text-blue" @click="openPage('/pages/user/agreement')">时物链条用户协议</span>
</view>
</view>
<p class="text-blue u-m-l-70">没有套路真实需求</p>
</view>
<view class="flex flex-nowrap">
<view class="flex-1"></view>
<view class="u-m-t-60 text-blue" @click="openPage('/pages/user/accountLogin')">已有账号去登录</view>
</view>
</view>
</template>
<script>
<script setup>
import { ref, computed, reactive } from 'vue';
import { useStore } from 'vuex';
import { onReady } from '@dcloudio/uni-app';
import userMixin from '@/hooks/user/userMixin'
const store = useStore();
const mixinInit = userMixin();
const signUpForm = ref(null);
const form = reactive({
phone: '',
verificationCodeValue: '', //
smsCode: '',
account: '',
password: ''
})
const renderData = reactive({
verificationCodeId: '', // id
imageBase64: '', //
checked: false
})
onReady(() => {
signUpForm.value.setRules(mixinInit.rules);
});
getImageCode(); //
const submit = () => {
signUpForm.value.validate(valid => {
if (valid) {
signUp()
}
});
}
async function signUp() {
uni.$ui.showLoading();
try {
if (!renderData.checked) {
uni.$ui.showToast('请阅读并同意使用用户协议');
return;
}
const params = {
account: form.account,
password: form.password,
phone: form.phone,
smsCode: form.smsCode
};
let res = await uni.$u.api.signup(params);
store.commit('user/setToken', res.token);
store.commit('user/setUser', res);
uni.$storage.setStorageSync('anyringToken', res.token || '');
uni.$storage.setStorageSync('user', JSON.stringify(res) || '');
uni.$ui.hideLoading();
uni.navigateTo({
url: '/pages/index/index'
});
} catch (error) {
uni.$ui.hideLoading();
uni.$ui.showToast(error);
}
}
//
async function getImageCode() {
uni.$ui.showLoading();
try {
const data = await uni.$u.api.getImageCode();
renderData.imageBase64 = data.imageBase64 || '';
renderData.verificationCodeId = data.verificationCodeId || '';
uni.$ui.hideLoading();
} catch (error) {
uni.$ui.hideLoading();
uni.$ui.showToast(error);
}
}
//
function changeChecked() {
renderData.checked = !renderData.checked;
}
function openPage(url) {
uni.navigateTo({
url: url
})
}
</script>
<style>
.code-image {
width: 200rpx;
height: 70rpx;
}
.text-blue {
color: #0081ff;
}
</style>

186
plugins/p-deliver/p-deliver.vue

@ -1,18 +1,198 @@
<template>
<!-- <view class="deliver-container">p-deliver</view> -->
<view class="my-2 bg-white p-2 rounded-md relative" @longpress="logoTime" v-if="deliverRef">
<!-- 插件名称输入和提交 -->
<view class="flex item-center justify-between py-3 pl-2" :class="inputRef">
<u-input v-model="iptValue" type="text" :border="false" placeholder="请编辑交付物名称" />
<view class="self-center" :class="viewRef">{{ iptValue }}</view>
<u-button type="primary" size="mini" @click="submit" class="self-center" :disabled="sbumitState">提交</u-button>
<u-icon v-show="historyIcon" name="arrow-right" class="ml-1" @click="historical"></u-icon>
</view>
<view :class="viewRef" class="py-3 pl-2">
<span class="relative px-1">
<u-badge :is-dot="true" is-center></u-badge>
{{ iptValue }}
</span>
</view>
<!-- 插件上传方式 -->
<view>
<u-input v-model="linkValue" type="text" :border="true" placeholder="请输入交付物地址/链接"> </u-input>
<view class="btns flexitems-start mt-3">
<u-button size="mini" :plain="true" style="color: #007aff" class="mr-3" @click="paste">粘贴</u-button>
<u-button size="mini" :plain="true" style="color: #007aff" class="mr-3" @click="getfile">文件</u-button>
<u-button size="mini" :plain="true" style="color: #007aff" class="mr-3" @click="photos">拍照</u-button>
</view>
</view>
<!-- 提示框 -->
<u-toast ref="tips" />
<!-- 取消和确定 -->
<u-mask :show="showRef" @click="showRef = false">
<view class="warp">
<view class="rect rounded-md" @tap.stop>
<view class="text-center my-7 font-semibold"> 交付物标题名称 </view>
<view class="">
<u-input :border="true" class="m-5" placeholder="请输入交付物名称" v-model="newInputRef" />
</view>
<view class="flex justify-around h-12 mt-7 justify-self-stretch" style="border-top: 1px solid #d1d5db">
<view class="leading-12 flex-1 text-center" style="border-right: 1px solid #d1d5db" @click="cancelClick"> 取消 </view>
<view class="text-blue-700 leading-12 flex-1 text-center" @click="sureClick"> 确定 </view>
</view>
</view>
</view>
</u-mask>
<!-- 编辑和删除的遮罩层 -->
<view class="mask flex items-center justify-center bg-grey" :class="maskRef" @click="close">
<view class="bg-yellow-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click="revisePlugin" @tap.stop>修改</view>
<view class="bg-red-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click="deletePlugin" @tap.stop>删除</view>
</view>
<!-- 插件审核人员选择 -->
<Reviewer />
</view>
<view class="box shadow-lg">
<view class="deliver-container">p-deliver</view>
</view>
</template>
<script setup>
import { ref, computed, reactive } from 'vue';
//
const deliverRef = ref(true);
const iptValue = ref('');
const linkValue = ref('');
const historyIcon = ref(false);
const tips = ref('');
const showRef = ref(false);
const maskRef = ref('hidden');
const inputRef = ref('block');
const viewRef = ref('hidden');
const newInputRef = ref('');
const submitHistory = reactive([]);
//
const sbumitState = computed(() => !(iptValue.value && linkValue.value));
//
function getTime() {
const MM = uni.$dayjs().$M + 1;
const DD = uni.$dayjs().$D;
const HH = uni.$dayjs().$H;
const mm = uni.$dayjs().$m;
const getTime = `${MM}/${DD} ${HH}:${mm < 10 ? `0${mm}` : mm}`;
return getTime;
}
//
function submit() {
const reg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?$/;
if (!reg.test(linkValue.value)) {
// toast
uni.$ui.showToast('请输入正确的链接');
} else {
inputRef.value = 'hidden';
viewRef.value = 'block';
const time = getTime();
const obj = {};
obj.name = iptValue.value;
obj.time = time;
obj.link = linkValue.value;
submitHistory.push(obj);
console.log(submitHistory);
}
}
//
function historical() {
uni.navigateTo({ url: '/pages/submitList/submitList' });
}
//
function paste() {
uni.getClipboardData({
success(res) {
linkValue.value = res.data;
},
});
}
//
function getfile() {
uni.chooseFile({
count: 1, // 100
extension: ['.zip', '.doc'],
success(res) {
linkValue.value = JSON.stringify(res.tempFilePaths);
},
});
}
//
function photos() {
uni.chooseImage({
count: 1, // 9
sizeType: ['original', 'compressed'], //
sourceType: ['album', 'camera'], //
success(res) {
linkValue.value = JSON.stringify(res.tempFilePaths);
},
});
}
function close() {
maskRef.value = 'hidden';
}
//
function logoTime() {
if (viewRef.value === 'block') {
maskRef.value = 'block';
}
}
//
function revisePlugin() {
showRef.value = true;
}
//
function cancelClick() {
showRef.value = false;
// maskRef.value = 'hidden'
}
//
function sureClick() {
iptValue.value = newInputRef.value;
newInputRef.value = '';
inputRef.value = 'block';
viewRef.value = 'hidden';
historyIcon.value = true;
showRef.value = false;
maskRef.value = 'hidden';
}
//
function deletePlugin() {
deliverRef.value = false;
}
</script>
<style scoped lang="scss">
.box{
<style lang="scss">
.warp {
display: flex;
align-items: center;
justify-content: center;
height: 80%;
}
.rect {
width: 80%;
height: 380rpx;
background-color: #fff;
}
.box {
border-radius: 8px;
background: #fff;
padding: 16px;
overflow: hidden;
}
}
</style>

9
plugins/p-task-title/p-task-title.vue

@ -1,5 +1,10 @@
<template>
<!-- 任务名插件 -->
<theme class="my-2">
<view class="bg-white rounded-md h-10 leading-10 pl-2">{{ task.name }}</view>
</theme>
<view class="box shadow-lg">
<view>{{ task.name }}</view>
</view>
@ -10,10 +15,10 @@ defineProps({ task: { type: Object, default: () => {} } });
</script>
<style scoped lang="scss">
.box{
.box {
border-radius: 8px;
background: #fff;
padding: 16px;
overflow: hidden;
}
}
</style>

69
project.config.json

@ -0,0 +1,69 @@
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"bundle": false,
"userConfirmedBundleSwitch": false,
"urlCheck": true,
"scopeDataCheck": false,
"coverView": true,
"es6": true,
"postcss": true,
"compileHotReLoad": false,
"lazyloadPlaceholderEnable": false,
"preloadBackgroundData": false,
"minified": true,
"autoAudits": false,
"newFeature": false,
"uglifyFileName": false,
"uploadWithSourceMap": true,
"useIsolateContext": true,
"nodeModules": false,
"enhance": true,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"showShadowRootInWxmlPanel": true,
"packNpmManually": false,
"enableEngineNative": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"showES6CompileOption": false,
"minifyWXML": true
},
"compileType": "miniprogram",
"libVersion": "2.21.3",
"appid": "wx0d9aabee071e228e",
"projectname": "TALL",
"debugOptions": {
"hidedInDevtools": []
},
"scripts": {},
"staticServerOptions": {
"baseURL": "",
"servePath": ""
},
"isGameTourist": false,
"condition": {
"search": {
"list": []
},
"conversation": {
"list": []
},
"game": {
"list": []
},
"plugin": {
"list": []
},
"gamePlugin": {
"list": []
},
"miniprogram": {
"list": []
}
}
}

2
store/socket/actions.js

@ -202,7 +202,7 @@ const actions = {
dispatch('sendHeart');
} else {
uni.$u.toast('消息系统认证失败, 请退出重新登录');
uni.$t.removeStorageSync('anyringToken');
uni.$storage.removeStorageSync('anyringToken');
commit('setSocket', null);
}
},

2
store/user/actions.js

@ -10,7 +10,7 @@ const actions = {
commit('setToken', res.token);
commit('setUser', res);
uni.$storage.setStorageSync('anyringToken', res.token || '');
uni.$storage.setStorageSync('user', JSON.stringify(res));
uni.$storage.setStorageSync('user', JSON.stringify(res) || '');
return res;
} catch (error) {
uni.$ui.showToast(error.msg || '获取个人信息失败');

18
utils/cacheAndRequest.js

@ -22,6 +22,7 @@ export default {
*/
getProjects(startTime, endTime, fn) {
let remote = false;
if (store.getters.useStorage) {
// 有缓存 且 服务端数据未返回 就先返回缓存
uni.$cache
@ -31,8 +32,7 @@ export default {
})
.catch(err => !remote && fn(err));
}
waitTokenRequest(() => {
// 拿到api数据后 再用api的数据
uni.$u.api
.getProjects(startTime, endTime)
.then(data => {
@ -42,7 +42,19 @@ export default {
uni.$cache.putProjects(data);
})
.catch(err => fn(err));
});
// waitTokenRequest(() => {
// // 拿到api数据后 再用api的数据
// uni.$u.api
// .getProjects(startTime, endTime)
// .then(data => {
// remote = true;
// fn(null, data);
// // 存api到cache里
// uni.$cache.putProjects(data);
// })
// .catch(err => fn(err));
// });
},
/**

11
utils/request.js

@ -22,6 +22,12 @@ export function setupHttp(app) {
config.header.Authorization = `Bearer ${token}`;
}
uni.getSystemInfo({
success: function (res) {
config.header.deviceId = res.deviceId;
}
})
return config;
};
@ -31,6 +37,11 @@ export function setupHttp(app) {
// res为服务端返回值,可能有code,result等字段
// 这里对res.result进行返回,将会在this.$u.post(url).then(res => {})的then回调中的res的到
// 如果配置了originalData为true,请留意这里的返回值
if (res.tokenObj.token) {
storage.setStorageSync('anyringToken', res.tokenObj.token || '');
store.commit('user/setToken', res.tokenObj.token);
}
return res.data;
} else if (res.code === 401) {
// 假设201为token失效,这里跳转登录

Loading…
Cancel
Save