28 changed files with 1537 additions and 743 deletions
@ -0,0 +1,19 @@ |
|||||
|
<template> |
||||
|
<!-- 标题部分 --> |
||||
|
<view> |
||||
|
ssss |
||||
|
</view> |
||||
|
<!-- 输入框 --> |
||||
|
<view> |
||||
|
|
||||
|
</view> |
||||
|
<!-- 按钮 --> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
</style> |
@ -1,480 +1,507 @@ |
|||||
<template> |
<template> |
||||
<view> |
<view> |
||||
<scroll-view scroll-y="true"> |
<scroll-view scroll-y="true"> |
||||
<view v-if="!data.changeEvent"> |
<view v-if="!data.changeEvent"> |
||||
<view :id="'cu-' + index" :key="item.id" class="cu-item flex-col" v-for="(item, index) in data.itemList"> |
<view :id="'cu-' + index" :key="item.id" class="cu-item flex-col" v-for="(item, index) in data.itemList"> |
||||
<ProjectItem |
<ProjectItem |
||||
class="w-full" |
class="w-full" |
||||
:index="index" |
:index="index" |
||||
:item="item" |
:item="item" |
||||
:menuList="data.menuList" |
:menuList="data.menuList" |
||||
@setData="setData" |
@setData="setData" |
||||
@openSubProject="openSubProject" |
@openSubProject="openSubProject" |
||||
/> |
/> |
||||
</view> |
</view> |
||||
</view> |
</view> |
||||
|
|
||||
<view v-else> |
<view v-else> |
||||
<view |
<view |
||||
:id="'cu-' + index" |
:id="'cu-' + index" |
||||
:key="index" |
:key="index" |
||||
:style="{ 'background-color': item.color }" |
:style="{ 'background-color': item.color }" |
||||
@touchend="stops($event, index)" |
@touchend="stops($event, index)" |
||||
@touchmove.stop.prevent="move" |
@touchmove.stop.prevent="move" |
||||
@touchstart="start($event, index)" |
@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> |
> |
||||
|
|
||||
<!-- 内容区 --> |
<view class="border-100 bg-blue-500" v-if="item.showTopBorder"></view> |
||||
<!-- 父项目 --> |
|
||||
<view class="w-full"> |
<!-- 内容区 --> |
||||
<view class="flex items-center justify-between p-3"> |
<!-- 父项目 --> |
||||
<u-icon class="mover" name="https://www.tall.wiki/staticrec/drag.svg" size="48"></u-icon> |
<view class="w-full"> |
||||
|
<view class="flex items-center justify-between p-3"> |
||||
<view class="flex-1 px-3"> |
<u-icon class="mover" name="https://www.tall.wiki/staticrec/drag.svg" size="48"></u-icon> |
||||
<view class="flex items-center mb-1"> |
|
||||
<view class="mr-2">{{ item.name }}</view> |
<view class="flex-1 px-3"> |
||||
<!-- 状态 TODO:--> |
<view class="flex items-center mb-1"> |
||||
<view class="px-2 text-xs text-green-400 bg-green-100 rounded-full flex-shrink-0">进行中</view> |
<view class="mr-2">{{ item.name }}</view> |
||||
</view> |
<!-- 状态 TODO:--> |
||||
|
<view class="px-2 text-xs text-green-400 bg-green-100 rounded-full flex-shrink-0">进行中</view> |
||||
<view class="flex items-center text-xs text-gray-400"> |
</view> |
||||
<view class="pr-2">{{ dayjs(+item.startTime).format('MM-DD HH:mm') }}</view> |
|
||||
至 |
<view class="flex items-center text-xs text-gray-400"> |
||||
<view class="pl-2">{{ dayjs(+item.endTime).format('MM-DD HH:mm') }}</view> |
<view class="pr-2">{{ dayjs(+item.startTime).format('MM-DD HH:mm') }}</view> |
||||
</view> |
至 |
||||
</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="openSubProject(item.sonProjectList.length, index)" class="text-gray-400" name="arrow-up" size="14px" v-if="item.show"></u-icon> |
<!-- 箭头 --> |
||||
<u-icon @click="openSubProject(item.sonProjectList.length, index)" class="text-gray-400" name="arrow-down" size="14px" v-else></u-icon> |
<view v-if="item.sonProjectList && item.sonProjectList.length"> |
||||
</view> |
<u-icon @click="openSubProject(item.sonProjectList.length, index)" class="text-gray-400" name="arrow-up" size="14px" v-if="item.show"></u-icon> |
||||
<u-icon class="text-gray-400" name="arrow-right" size="14px" v-else></u-icon> |
<u-icon @click="openSubProject(item.sonProjectList.length, index)" class="text-gray-400" name="arrow-down" size="14px" v-else></u-icon> |
||||
</view> |
</view> |
||||
<!-- 父项目 end --> |
<u-icon class="text-gray-400" name="arrow-right" size="14px" v-else></u-icon> |
||||
|
</view> |
||||
<!-- 子项目 --> |
<!-- 父项目 end --> |
||||
<view class="ml-8" v-if="item.show"> |
|
||||
<view :id="'cu-' + index + '-' + subIndex" :key="subIndex" |
<!-- 子项目 --> |
||||
@touchend.stop.prevent="stops($event, index + '-' + subIndex, item.sonProjectList.length)" |
<view class="ml-8" v-if="item.show"> |
||||
@touchmove.stop.prevent="move($event, item.sonProjectList.length)" |
<view |
||||
@touchstart.stop.prevent="start($event, index + '-' + subIndex)" |
:id="'cu-' + index + '-' + subIndex" |
||||
class="cu-item flex-col" v-for="(subItem, subIndex) in item.sonProjectList"> |
:key="subIndex" |
||||
<view class="flex items-center justify-between p-3 w-full"> |
@touchend.stop.prevent="stops($event, index + '-' + subIndex, item.sonProjectList.length)" |
||||
<u-icon class="mover" name="https://www.tall.wiki/staticrec/drag.svg" size="48"> |
@touchmove.stop.prevent="move($event, item.sonProjectList.length)" |
||||
</u-icon> |
@touchstart.stop.prevent="start($event, index + '-' + subIndex)" class="cu-item flex-col" |
||||
|
v-for="(subItem, subIndex) in item.sonProjectList" |
||||
<view class="flex-1 px-3"> |
> |
||||
<view class="flex items-center"> |
|
||||
<view class="mr-2">{{ subItem.name }}</view> |
<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> |
||||
<view |
|
||||
:class=" |
<view class="flex-1 px-3"> |
||||
subItem.status === 0 |
<view class="flex items-center"> |
||||
? 'text-blue-400 bg-blue-100' |
<view class="mr-2">{{ subItem.name }}</view> |
||||
: subItem.status === 1 |
<!-- 状态 --> |
||||
? 'text-green-400 bg-green-100' |
<view |
||||
: subItem.status === 2 |
:class=" |
||||
? 'text-red-400 bg-red-100' |
subItem.status === 0 |
||||
: 'text-gray-400 bg-gray-100' |
? 'text-blue-400 bg-blue-100' |
||||
" |
: subItem.status === 1 |
||||
class="px-2 text-xs text-gray-400 bg-gray-100 rounded-full flex-shrink-0"> |
? 'text-green-400 bg-green-100' |
||||
{{ subItem.status === 0 ? '未开始' : subItem.status === 1 ? '进行中' : subItem.status === 2 ? '暂停' : '已完成' }} |
: subItem.status === 2 |
||||
</view> |
? 'text-red-400 bg-red-100' |
||||
</view> |
: 'text-gray-400 bg-gray-100' |
||||
</view> |
" |
||||
|
class="px-2 text-xs text-gray-400 bg-gray-100 rounded-full flex-shrink-0"> |
||||
<!-- 箭头 --> |
{{ subItem.status === 0 ? '未开始' : subItem.status === 1 ? '进行中' : subItem.status === 2 ? '暂停' : '已完成' }} |
||||
<u-icon class="text-gray-400" name="arrow-right" size="14px"></u-icon> |
</view> |
||||
</view> |
</view> |
||||
</view> |
</view> |
||||
</view> |
|
||||
</view> |
<!-- 箭头 --> |
||||
<!-- 内容区 end --> |
<u-icon class="text-gray-400" name="arrow-right" size="14px"></u-icon> |
||||
|
</view> |
||||
<view class="border-100 bg-blue-500" v-if="item.showBorder"></view> |
</view> |
||||
<view class="border-80 bg-blue-500" v-if="item.showSubBorder"></view> |
</view> |
||||
</view> |
</view> |
||||
</view> |
<!-- 内容区 end --> |
||||
</scroll-view> |
|
||||
|
<view class="border-100 bg-blue-500" v-if="item.showBorder"></view> |
||||
<!-- 移动悬浮 begin --> |
<view class="border-80 bg-blue-500" v-if="item.showSubBorder"></view> |
||||
<view v-if="data.showMoveImage"> |
</view> |
||||
<view :style="{ left: moveLeft + 'px', top: moveTop + 'px' }" class="cu-item absolute"> |
</view> |
||||
<ProjectItem class="w-full" :item="moveItem" /> |
</scroll-view> |
||||
</view> |
|
||||
</view> |
<!-- 移动悬浮 begin --> |
||||
<!-- 移动悬浮 end --> |
<view v-if="data.showMoveImage"> |
||||
|
<view :style="{ left: data.moveLeft + 'px', top: data.moveTop + 'px' }" class="cu-item absolute"> |
||||
<!-- 项目操作面板 --> |
<ProjectItem class="w-full" :item="data.moveItem" /> |
||||
<u-action-sheet :list="data.menuList" :tips="data.tips" @click="chooseAction" v-model="data.showMenu"></u-action-sheet> |
</view> |
||||
</view> |
</view> |
||||
|
<!-- 移动悬浮 end --> |
||||
|
|
||||
|
<!-- 项目操作面板 --> |
||||
|
<u-action-sheet :list="data.menuList" :tips="data.tips" @click="chooseAction" v-model="data.showMenu"></u-action-sheet> |
||||
|
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
import { ref, onMounted, watch, computed } from 'vue'; |
import { reactive, onMounted, watch, computed } from 'vue'; |
||||
import ProjectItem from '@/components/Projects/ProjectItem.vue'; |
import ProjectItem from '@/components/Projects/ProjectItem.vue'; |
||||
import { useStore } from 'vuex'; |
import { useStore } from 'vuex'; |
||||
import dayjs from 'dayjs'; |
import dayjs from 'dayjs'; |
||||
|
|
||||
const store = useStore(); |
const store = useStore(); |
||||
const projects = computed(() => store.state.project.projects); |
const projects = computed(() => store.state.project.projects); |
||||
const data = ref({ |
const data = reactive({ |
||||
itemTop: 0, |
// itemTop: 0, |
||||
itemLeft: 0, |
// itemLeft: 0, |
||||
itemHeight: 0, // 移动元素的高度 |
itemHeight: 0, // 移动元素的高度 |
||||
subItemHeight: 0, // 移动子元素的高度 |
itemWidth: 0, // 移动元素的宽度 |
||||
itemWidth: 0, // 移动元素的宽度 |
subItemHeight: 0, // 移动子元素的高度 |
||||
showMoveImage: false, |
showMoveImage: false, |
||||
moveItem: '', |
moveItem: '', // 当前选中的项目信息 |
||||
moveLeft: 0, |
moveLeft: 0, // 当前选中项目距左侧的距离 |
||||
moveTop: 0, |
moveTop: 0, // 当前选中项目距顶部的距离 |
||||
deltaLeft: 0, |
deltaLeft: 0, |
||||
deltaTop: 0, |
deltaTop: 0, |
||||
beginleft: 0, |
beginleft: 0, // 项目列表中第一个项目初始时距离左侧的距离 |
||||
begintop: 0, |
begintop: 0, // 项目列表中第一个项目初始时距离顶部的距离 |
||||
itemList: [], |
itemList: [], // 项目列表 |
||||
setSubItem: false, |
setSubItem: false, // 选中的是否是二级项目 |
||||
changeEvent: false, |
changeEvent: false, // 是否点击过操作面板 |
||||
|
showMenu: false, |
||||
showMenu: false, |
tips: { text: '', color: '#909399', fontSize: 28, }, |
||||
tips: { |
projectId: 0, |
||||
text: '', |
menuList: [{ text: '复制' }, { text: '编辑' }, { text: '删除' }, { text: '置顶' }, { text: '排序' }], |
||||
color: '#909399', |
// show: false, |
||||
fontSize: 28, |
// border: 'border border-blue-500 shadow rounded-md', |
||||
}, |
showBorder: false, // 一级项目底部边框是否显示 |
||||
projectId: 0, |
showItemIndex: undefined, |
||||
menuList: [{ text: '复制' }, { text: '编辑' }, { text: '删除' }, { text: '置顶' }, { text: '排序' }], |
}); |
||||
// show: false, |
|
||||
border: 'border border-blue-500 shadow rounded-md', |
const emit = defineEmits(['changeHeight', 'change']); |
||||
showBorder: false, |
|
||||
showItemIndex: undefined, |
|
||||
}); |
|
||||
|
|
||||
watch(projects, (val) => { |
|
||||
data.value.itemList = val; |
|
||||
data.value.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; |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
// 展开子项目 |
|
||||
function openSubProject(length, index) { |
|
||||
setProjectItemShow({ index, show: data.value.itemList[index].show ? false : true }); |
|
||||
if (length && index) { |
|
||||
this.$emit('changeHeight', length, index); |
|
||||
} |
|
||||
data.value.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; |
|
||||
}).exec(); |
|
||||
} |
|
||||
|
|
||||
function setData(flag, projectId, tips) { |
|
||||
data.value.showMenu = flag; |
|
||||
data.value.projectId = projectId; |
|
||||
data.value.tips = tips; |
|
||||
} |
|
||||
|
|
||||
function chooseAction(e) { |
|
||||
let obj = { index: e, projectId: data.value.projectId }; |
|
||||
// this.$emit('chooseAction', data); |
|
||||
actionFun(obj); |
|
||||
} |
|
||||
|
|
||||
// 操作 |
|
||||
function actionFun(obj) { |
|
||||
let action = data.value.menuList[obj.index].text; |
|
||||
if (action === '排序') { |
|
||||
data.value.changeEvent = true; |
|
||||
uni.$ui.showToast('请移动进行排序'); |
|
||||
} |
|
||||
|
|
||||
if (action === '删除') { |
|
||||
data.value.changeEvent = false; |
|
||||
delProject(obj.projectId); |
|
||||
} |
|
||||
|
|
||||
if (data.value.showItemIndex !== undefined) { |
// 监听项目列表 |
||||
setProjectItemShow({ index: data.value.showItemIndex, show: true }); |
watch(projects, (val) => { |
||||
} |
data.itemList = val; |
||||
|
data.itemList.forEach(item => { |
||||
|
item.showBorder = false; // 一级项目底部边框是否显示 |
||||
|
item.showSubBorder = false; // 一级项目底部边框是否显示 |
||||
|
item.showTopBorder = false; // 一级项目顶部边框是否显示 |
||||
|
}); |
||||
|
}) |
||||
|
|
||||
|
onMounted(() => { |
||||
|
data.itemList = projects.value; |
||||
|
data.itemList.forEach(item => { |
||||
|
item.showBorder = false; // 一级项目底部边框是否显示 |
||||
|
item.showSubBorder = false; // 一级项目底部边框是否显示 |
||||
|
item.showTopBorder = false; // 一级项目顶部边框是否显示 |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
// 展开子项目 |
||||
|
function openSubProject(length, index) { |
||||
|
store.commit('project/setProjectItemShow', { index, show: data.itemList[index].show ? false : true }); |
||||
|
if (length && index) { |
||||
|
emit('changeHeight', length, index); |
||||
} |
} |
||||
|
data.showItemIndex = index; |
||||
function isNumber(val) { |
} |
||||
return val === +val; |
|
||||
} |
// 获取项目列表距离顶部的距离 |
||||
|
function getDate() { |
||||
function start(e, index) { |
const query = uni.createSelectorQuery().select(`#cu-0`).fields({ |
||||
console.log('开始', e); |
id: true, |
||||
setTimeout(() => { |
dataset: true, |
||||
getDate(); |
rect: true, |
||||
}, 300); |
size: true |
||||
|
}, res => { |
||||
if (isNumber(index)) { |
data.begintop = res.top; |
||||
data.value.setSubItem = false; |
data.beginleft = res.left; |
||||
const query = uni.createSelectorQuery().in(this); |
}).exec(); |
||||
console.log('2222', query) |
} |
||||
query.select(`#cu-${index}`).boundingClientRect(res => { |
|
||||
data.value.moveTop = res.top; |
function setData(flag, projectId, tips) { |
||||
data.value.moveLeft = res.left; |
data.showMenu = flag; |
||||
data.value.moveItem = data.value.itemList[index]; |
data.projectId = projectId; |
||||
data.value.itemWidth = res.width; |
data.tips = tips; |
||||
data.value.itemHeight = res.height; |
} |
||||
}).exec(); |
|
||||
} else { |
function chooseAction(e) { |
||||
let arr = index.split('-'); |
let obj = { |
||||
data.value.setSubItem = true; |
index: e, |
||||
const query = uni.createSelectorQuery().in(this); |
projectId: data.projectId |
||||
query.select(`#cu-${arr[0] - 0}`).boundingClientRect(res => { |
}; |
||||
data.value.itemHeight = res.height; |
// emit('chooseAction', data); |
||||
}).exec(); |
actionFun(obj); |
||||
|
} |
||||
query.select(`#cu-${index}`).boundingClientRect(res => { |
|
||||
data.value.moveTop = res.top; |
// 操作 |
||||
data.value.moveLeft = res.left; |
function actionFun(obj) { |
||||
data.value.moveItem = data.value.itemList[arr[0] - 0].sonProjectList[arr[1] - 0]; |
let action = data.menuList[obj.index].text; |
||||
data.value.itemWidth = res.width; |
if (action === '排序') { |
||||
data.value.subItemHeight = res.height; |
data.changeEvent = true; |
||||
}).exec(); |
uni.$ui.showToast('请移动进行排序'); |
||||
} |
|
||||
} |
|
||||
|
|
||||
function move(e, length) { |
|
||||
console.log('移动'); |
|
||||
data.value.showMoveImage = true; //悬浮开始 |
|
||||
const touch = e.touches[0]; |
|
||||
if (data.value.deltaLeft == 0) { |
|
||||
// 获得本身的移动 |
|
||||
data.value.deltaLeft = touch.pageX - data.value.moveLeft; |
|
||||
data.value.deltaTop = touch.pageY - data.value.moveTop; |
|
||||
} |
|
||||
data.value.moveLeft = touch.pageX - data.value.deltaLeft; |
|
||||
data.value.moveTop = touch.pageY - data.value.deltaTop; |
|
||||
|
|
||||
let lastIndex = (lastIndex = findOverIndex(touch.pageY, length)); |
|
||||
console.log('111111', lastIndex); |
|
||||
// 显示下划线 |
|
||||
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; |
|
||||
if (i === lastIndex) { |
|
||||
data.value.itemList[i].showSubBorder = true; |
|
||||
} else { |
|
||||
data.value.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; |
|
||||
} else { |
|
||||
data.value.itemList[i].showSubBorder = false; |
|
||||
data.value.itemList[i].showTopBorder = false; |
|
||||
if (i === lastIndex) { |
|
||||
data.value.itemList[i].showBorder = true; |
|
||||
} else { |
|
||||
data.value.itemList[i].showBorder = false; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
} |
||||
|
|
||||
function stops(e, index, length) { |
if (action === '删除') { |
||||
console.log('结束'); |
data.changeEvent = false; |
||||
const touch = e.mp.changedTouches[0]; |
delProject(obj.projectId); |
||||
let lastIndex = (lastIndex = findOverIndex(touch.pageY, length)); |
} |
||||
|
|
||||
|
if (data.showItemIndex !== undefined) { |
||||
|
store.commit('project/setProjectItemShow', { |
||||
|
index: data.showItemIndex, |
||||
|
show: true |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function isNumber(val) { |
||||
|
return val === +val; |
||||
|
} |
||||
|
|
||||
|
function start(e, index) { |
||||
|
console.log('开始'); |
||||
|
setTimeout(() => { |
||||
|
getDate(); |
||||
|
}, 300); |
||||
|
|
||||
|
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 { // 选中二级项目 |
||||
|
let arr = index.split('-'); |
||||
|
data.setSubItem = true; |
||||
|
|
||||
// 交换两个值 |
const query = uni.createSelectorQuery(); |
||||
for (let i = 0; i < data.value.itemList.length; i++) { |
query.select(`#cu-${arr[0] - 0}`).fields({ |
||||
// 插入顶部 |
id: true, |
||||
if (data.value.itemList[i].showTopBorder) { |
dataset: true, |
||||
if (isNumber(index)) { |
rect: true, |
||||
let Value = data.value.itemList[index]; |
size: true |
||||
data.value.itemList.unshift(Value); |
}, res => { |
||||
data.value.itemList.splice(index + 1, 1); |
data.itemHeight = res.height; |
||||
} else { |
}).exec(); |
||||
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); |
|
||||
const options = { |
|
||||
id: Value.id, |
|
||||
parentId: 0, |
|
||||
}; |
|
||||
this.$emit('change', options); |
|
||||
} |
|
||||
// 清空 |
|
||||
clearSet(i); |
|
||||
this.$emit('change', data.value.itemList); |
|
||||
return; |
|
||||
} |
|
||||
// 插入一级项目 |
|
||||
if (data.value.itemList[i].showBorder) { |
|
||||
if (isNumber(index)) { |
|
||||
let Value = data.value.itemList[index]; |
|
||||
data.value.itemList.splice(i + 1, 0, Value); |
|
||||
if (i < index) { |
|
||||
data.value.itemList.splice(index + 1, 1); |
|
||||
} else { |
|
||||
data.value.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); |
|
||||
const options = { |
|
||||
id: Value.id, |
|
||||
parentId: 0, |
|
||||
}; |
|
||||
this.$emit('change', options); |
|
||||
} |
|
||||
// 清空 |
|
||||
clearSet(i); |
|
||||
this.$emit('change', data.value.itemList); |
|
||||
return; |
|
||||
} |
|
||||
// 插入二级项目 |
|
||||
if (data.value.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); |
|
||||
} else { |
|
||||
data.value.itemList[lastIndex].sonProjectList = [Value]; |
|
||||
} |
|
||||
data.value.itemList.splice(index, 1); |
|
||||
// 清空 |
|
||||
clearSet(i); |
|
||||
const options = { |
|
||||
id: Value.id, |
|
||||
parentId: data.value.itemList[lastIndex - 1].id, |
|
||||
}; |
|
||||
this.$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); |
|
||||
} else { |
|
||||
data.value.itemList[lastIndex].sonProjectList = [Value]; |
|
||||
} |
|
||||
data.value.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1); |
|
||||
// 清空 |
|
||||
clearSet(i); |
|
||||
const options = { |
|
||||
id: Value.id, |
|
||||
parentId: data.value.itemList[lastIndex].id, |
|
||||
}; |
|
||||
this.$emit('change', options); |
|
||||
|
|
||||
const options1 = { |
query.select(`#cu-${index}`).fields({ |
||||
id: Value.id, |
id: true, |
||||
parentId: 0, |
dataset: true, |
||||
}; |
rect: true, |
||||
this.$emit('change', options1); |
size: true |
||||
} |
}, res => { |
||||
return; |
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 clearSet(i) { |
function move(e, length) { |
||||
data.value.itemList[i].showBorder = false; |
console.log('移动'); |
||||
data.value.itemList[i].showSubBorder = false; |
data.showMoveImage = true; //悬浮开始 |
||||
data.value.itemList[i].showTopBorder = false; |
const touch = e.touches[0]; |
||||
data.value.deltaLeft == 0; |
if (data.deltaLeft == 0) { |
||||
data.value.showMoveImage = false; |
// 获得本身的移动 |
||||
data.value.setSubItem = false; |
data.deltaLeft = touch.pageX - data.moveLeft; |
||||
data.value.changeEvent = false; |
data.deltaTop = touch.pageY - data.moveTop; |
||||
data.value.showItemIndex = undefined; |
} |
||||
} |
data.moveLeft = touch.pageX - data.deltaLeft; |
||||
|
data.moveTop = touch.pageY - data.deltaTop; |
||||
// 找到停下的元素的下标 |
|
||||
function findOverIndex(posY) { |
let lastIndex = findOverIndex(touch.pageY, length); |
||||
// 如果有子项目展开着 |
// 显示下划线 |
||||
let leng = data.value.itemList.length * data.value.itemHeight; // 最后一个元素距离顶部的距离 |
for (let i = 0; i < data.itemList.length; i++) { |
||||
if (posY < data.value.begintop) { |
if (data.moveLeft > 35) { |
||||
return -1; |
data.itemList[i].showBorder = false; |
||||
} |
data.itemList[i].showTopBorder = false; |
||||
for (var i = 0; i < data.value.itemList.length; i++) { |
if (i === lastIndex) { |
||||
let begin = data.value.itemHeight * i + data.value.begintop; |
data.itemList[i].showSubBorder = true; |
||||
let end = data.value.itemHeight * i + data.value.begintop + data.value.itemHeight; |
} else { |
||||
if (begin <= posY && end >= posY) { |
data.itemList[i].showSubBorder = false; |
||||
return i; |
} |
||||
} |
} else { |
||||
} |
if (lastIndex === -1) { |
||||
if (posY > leng) { |
data.itemList[0].showTopBorder = true; |
||||
// 交换最后一个 |
data.itemList[i].showSubBorder = false; |
||||
return data.value.itemList.length - 1; |
data.itemList[i].showBorder = false; |
||||
} else if (posY < data.value.begintop) { |
} else { |
||||
return 0; |
data.itemList[i].showSubBorder = false; |
||||
} |
data.itemList[i].showTopBorder = false; |
||||
} |
if (i === lastIndex) { |
||||
|
data.itemList[i].showBorder = true; |
||||
// 删除项目 |
} else { |
||||
function delProject(id) { |
data.itemList[i].showBorder = false; |
||||
uni.showModal({ |
} |
||||
title: '', |
} |
||||
content: '是否删除项目?', |
} |
||||
showCancel: true, |
} |
||||
success: async ({ confirm }) => { |
} |
||||
if (confirm) { |
|
||||
await this.$u.api.delProject(id); |
function stops(e, index, length) { |
||||
let flag_index = 0; |
console.log('结束'); |
||||
data.value.itemList.forEach((item, index) => { |
const touch = e.changedTouches[0]; |
||||
if (item.id == id) { |
let lastIndex = findOverIndex(touch.pageY, length); |
||||
flag_index = index; |
|
||||
} |
// 交换两个值 |
||||
}); |
for (let i = 0; i < data.itemList.length; i++) { |
||||
|
// 插入顶部 |
||||
data.value.itemList.splice(flag_index, 1); |
if (data.itemList[i].showTopBorder) { |
||||
setProjects(data.value.itemList); |
if (isNumber(index)) { |
||||
} |
let Value = data.itemList[index]; |
||||
}, |
data.itemList.unshift(Value); |
||||
}); |
data.itemList.splice(index + 1, 1); |
||||
} |
} else { |
||||
|
let arr = index.split('-'); |
||||
|
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, |
||||
|
}; |
||||
|
emit('change', options); |
||||
|
} |
||||
|
// 清空 |
||||
|
clearSet(i); |
||||
|
emit('change', data.itemList); |
||||
|
return; |
||||
|
} |
||||
|
// 插入一级项目 |
||||
|
if (data.itemList[i].showBorder) { |
||||
|
if (isNumber(index)) { |
||||
|
let Value = data.itemList[index]; |
||||
|
data.itemList.splice(i + 1, 0, Value); |
||||
|
if (i < index) { |
||||
|
data.itemList.splice(index + 1, 1); |
||||
|
} else { |
||||
|
data.itemList.splice(index, 1); |
||||
|
} |
||||
|
} else { |
||||
|
let arr = index.split('-'); |
||||
|
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, |
||||
|
}; |
||||
|
emit('change', options); |
||||
|
} |
||||
|
// 清空 |
||||
|
clearSet(i); |
||||
|
emit('change', data.itemList); |
||||
|
return; |
||||
|
} |
||||
|
// 插入二级项目 |
||||
|
if (data.itemList[i].showSubBorder) { |
||||
|
if (isNumber(index)) { |
||||
|
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.itemList[lastIndex].sonProjectList = [Value]; |
||||
|
} |
||||
|
data.itemList.splice(index, 1); |
||||
|
// 清空 |
||||
|
clearSet(i); |
||||
|
const options = { |
||||
|
id: Value.id, |
||||
|
parentId: data.itemList[lastIndex - 1].id, |
||||
|
}; |
||||
|
emit('change', options); |
||||
|
} else { |
||||
|
let arr = index.split('-'); |
||||
|
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.itemList[lastIndex].sonProjectList = [Value]; |
||||
|
} |
||||
|
data.itemList[arr[0] - 0].sonProjectList.splice([arr[1] - 0], 1); |
||||
|
// 清空 |
||||
|
clearSet(i); |
||||
|
const options = { |
||||
|
id: Value.id, |
||||
|
parentId: data.itemList[lastIndex].id, |
||||
|
}; |
||||
|
emit('change', options); |
||||
|
|
||||
|
const options1 = { |
||||
|
id: Value.id, |
||||
|
parentId: 0, |
||||
|
}; |
||||
|
emit('change', options1); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 还原初始数据 |
||||
|
function clearSet(i) { |
||||
|
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.itemList.length * data.itemHeight; // 最后一个元素距离顶部的距离 |
||||
|
if (posY < data.begintop) { |
||||
|
return -1; |
||||
|
} |
||||
|
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.itemList.length - 1; |
||||
|
} else if (posY < data.begintop) { |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 删除项目 |
||||
|
function delProject(id) { |
||||
|
uni.showModal({ |
||||
|
title: '', |
||||
|
content: '是否删除项目?', |
||||
|
showCancel: true, |
||||
|
success: async ({ |
||||
|
confirm |
||||
|
}) => { |
||||
|
if (confirm) { |
||||
|
await uni.$u.api.delProject(id); |
||||
|
let flag_index = 0; |
||||
|
data.itemList.forEach((item, index) => { |
||||
|
if (item.id == id) { |
||||
|
flag_index = index; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
data.itemList.splice(flag_index, 1); |
||||
|
store.commit('project/setProjects', data.itemList); |
||||
|
} |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<style lang="scss" scoped> |
<style lang="scss" scoped> |
||||
.cu-item { |
.cu-item { |
||||
width: 100%; |
width: 100%; |
||||
display: flex; |
display: flex; |
||||
align-items: center; |
align-items: center; |
||||
font-size: 14px; |
font-size: 14px; |
||||
} |
} |
||||
|
|
||||
.border-100 { |
.border-100 { |
||||
width: 92%; |
width: 92%; |
||||
height: 4rpx; |
height: 4rpx; |
||||
} |
} |
||||
|
|
||||
.border-80 { |
.border-80 { |
||||
width: 84%; |
width: 84%; |
||||
height: 2px; |
height: 2px; |
||||
margin-left: 30px; |
margin-left: 30px; |
||||
} |
} |
||||
</style> |
</style> |
||||
|
@ -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> |
@ -1,141 +1,148 @@ |
|||||
<template> |
<template> |
||||
<!-- <view class="flex flex-col h-full bg-gray-50" @click="openAuth"> --> |
<!-- <view class="flex flex-col h-full bg-gray-50" @click="openAuth"> --> |
||||
<view class="flex flex-col h-full bg-gray-50"> |
<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 --> |
<Calendar @selected-change="onDateChange" :show-back="true" ref="calendar" @handleFindPoint="handleFindPoint" /> |
||||
<Upload @success="onUploadSuccess" @error="onUploadError" /> |
<!-- 上传 导入wbs --> |
||||
</view> |
<Upload @success="onUploadSuccess" @error="onUploadError" /> |
||||
<u-button @click="toLogin">登录</u-button> |
</view> |
||||
<!-- 项目列表 --> |
|
||||
<Projects @getProjects="getProjects" class="flex-1 overflow-y-auto" /> |
<u-button class="mt-4" @click="toLogin">登录</u-button> |
||||
|
<!-- 项目列表 --> |
||||
<!-- 全局提示框 --> |
<Projects @getProjects="getProjects" class="flex-1 overflow-y-auto" /> |
||||
<u-top-tips ref="uTips"></u-top-tips> |
|
||||
</view> |
<!-- 全局提示框 --> |
||||
|
<u-top-tips ref="uTips"></u-top-tips> |
||||
|
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
import { reactive, computed, watchEffect, ref } from 'vue'; |
import { reactive, computed, watchEffect, ref } from 'vue'; |
||||
import { useStore } from 'vuex'; |
import { useStore } from 'vuex'; |
||||
import dayjs from 'dayjs'; |
import dayjs from 'dayjs'; |
||||
|
|
||||
const store = useStore(); |
const store = useStore(); |
||||
const token = computed(() => store.state.user.token); |
const token = computed(() => store.state.user.token); |
||||
const uTips = ref(null); |
const uTips = ref(null); |
||||
|
|
||||
const data = reactive({ |
const data = reactive({ |
||||
calendar: null, |
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); |
|
||||
uni.$catchReq.getProjects(start, end, (err, data) => { |
|
||||
if (err) { |
|
||||
console.error('err: ', err); |
|
||||
} else { |
|
||||
data.forEach(item => { |
|
||||
item.show = false; |
|
||||
}); |
|
||||
store.commit('project/setProjects', data); |
|
||||
} |
|
||||
}); |
}); |
||||
} |
|
||||
|
getProjects(); |
||||
async function handleFindPoint(start, end) { |
handleFindPoint(); |
||||
try { |
|
||||
const startTime = start || dayjs().startOf('month').valueOf(); |
// 监听token |
||||
const endTime = end || dayjs().endOf('month').valueOf(); |
// watchEffect(() => { |
||||
const res = await uni.$u.api.findRedPoint(startTime, endTime); |
// if (!token.value) return; |
||||
store.commit('project/setDotList', res); |
// if (token.value) { |
||||
} catch (error) { |
// getProjects(); |
||||
console.log('error: ', error); |
// handleFindPoint(); |
||||
} |
// } |
||||
} |
|
||||
|
|
||||
// 点击了某个日期 |
|
||||
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 = () => { |
|
||||
uni.$ui.showToast('导入成功,即将打开新项目', 3000); |
|
||||
// uTips.show({ |
|
||||
// title: '导入成功,即将打开新项目', |
|
||||
// type: 'success', |
|
||||
// duration: '3000', |
|
||||
// }); |
|
||||
}; |
|
||||
|
|
||||
// 导入失败 |
|
||||
const onUploadError = error => { |
|
||||
uni.$ui.showToast('导入失败', 6000); |
|
||||
// uTips.show({ |
|
||||
// title: error || '导入失败', |
|
||||
// type: 'error', |
|
||||
// duration: '6000', |
|
||||
// }); |
// }); |
||||
}; |
|
||||
|
// 获取项目列表 |
||||
// 监听触摸滑动 切换日历的模式 月/周 |
function getProjects(start = dayjs().startOf('day').valueOf(), end = dayjs().endOf('day').valueOf()) { |
||||
function onMove(event) { |
uni.$catchReq.getProjects(start, end, (err, data) => { |
||||
const y = event.changedTouches[0].pageY; |
if (err) { |
||||
if (y - prevY > 0) { |
console.error('err: ', err); |
||||
// 向下滑动 如果是周视图weekMode=true 就 变成 月视图weekMode=false |
} else { |
||||
data.value.calendar.weekMode && (data.value.calendar.weekMode = false); |
data.forEach(item => { |
||||
} else if (y - prevY < 0) { |
item.show = false; |
||||
// 向上滑动 如果是月视图weekMode=false 就变成 周视图weekMode=true |
}); |
||||
!data.value.calendar.weekMode && (data.value.calendar.weekMode = true); |
store.commit('project/setProjects', data); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async function handleFindPoint(start, end) { |
||||
|
try { |
||||
|
const startTime = start || dayjs().startOf('month').valueOf(); |
||||
|
const endTime = end || dayjs().endOf('month').valueOf(); |
||||
|
const res = await uni.$u.api.findRedPoint(startTime, endTime); |
||||
|
store.commit('project/setDotList', res); |
||||
|
} catch (error) { |
||||
|
console.log('error: ', error); |
||||
|
} |
||||
} |
} |
||||
prevY = y; |
|
||||
data.value.calendar.initDate(); |
|
||||
} |
|
||||
|
|
||||
function toLogin() { |
// 点击了某个日期 |
||||
uni.navigateTo({ url: '/pages/user/accountLogin' }); |
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 = () => { |
||||
|
uni.$ui.showToast('导入成功,即将打开新项目', 3000); |
||||
|
// uTips.show({ |
||||
|
// title: '导入成功,即将打开新项目', |
||||
|
// type: 'success', |
||||
|
// duration: '3000', |
||||
|
// }); |
||||
|
}; |
||||
|
|
||||
|
// 导入失败 |
||||
|
const onUploadError = error => { |
||||
|
uni.$ui.showToast('导入失败', 6000); |
||||
|
// uTips.show({ |
||||
|
// title: error || '导入失败', |
||||
|
// type: 'error', |
||||
|
// duration: '6000', |
||||
|
// }); |
||||
|
}; |
||||
|
|
||||
|
// 监听触摸滑动 切换日历的模式 月/周 |
||||
|
// 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' |
||||
|
}) |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<style> |
<style> |
||||
.content { |
.content { |
||||
display: flex; |
display: flex; |
||||
flex-direction: column; |
flex-direction: column; |
||||
align-items: center; |
align-items: center; |
||||
justify-content: center; |
justify-content: center; |
||||
} |
} |
||||
|
|
||||
.logo { |
.logo { |
||||
height: 200rpx; |
height: 200rpx; |
||||
width: 200rpx; |
width: 200rpx; |
||||
margin-top: 200rpx; |
margin-top: 200rpx; |
||||
margin-left: auto; |
margin-left: auto; |
||||
margin-right: auto; |
margin-right: auto; |
||||
margin-bottom: 50rpx; |
margin-bottom: 50rpx; |
||||
} |
} |
||||
|
|
||||
.text-area { |
.text-area { |
||||
display: flex; |
display: flex; |
||||
justify-content: center; |
justify-content: center; |
||||
} |
} |
||||
|
|
||||
.title { |
.title { |
||||
font-size: 36rpx; |
font-size: 36rpx; |
||||
color: #8f8f94; |
color: #8f8f94; |
||||
} |
} |
||||
</style> |
</style> |
||||
|
@ -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> |
@ -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> |
@ -1,8 +1,159 @@ |
|||||
<template> |
<template> |
||||
</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> |
||||
|
|
||||
<script> |
<u-form-item label="图形验证码" prop="verificationCodeValue" label-width="160"> |
||||
</script> |
<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 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> |
<style> |
||||
|
.code-image { |
||||
|
width: 200rpx; |
||||
|
height: 70rpx; |
||||
|
} |
||||
|
|
||||
|
.text-blue { |
||||
|
color: #0081ff; |
||||
|
} |
||||
</style> |
</style> |
||||
|
@ -1,18 +1,198 @@ |
|||||
<template> |
<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="box shadow-lg"> |
||||
<view class="deliver-container">p-deliver</view> |
<view class="deliver-container">p-deliver</view> |
||||
</view> |
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<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([]); |
||||
|
|
||||
</script> |
// 判断提交按钮的状态 |
||||
|
const sbumitState = computed(() => !(iptValue.value && linkValue.value)); |
||||
|
|
||||
<style scoped lang="scss"> |
// 获取当前时间 |
||||
.box{ |
function getTime() { |
||||
border-radius: 8px; |
const MM = uni.$dayjs().$M + 1; |
||||
background: #fff; |
const DD = uni.$dayjs().$D; |
||||
padding: 16px; |
const HH = uni.$dayjs().$H; |
||||
overflow: hidden; |
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 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> |
</style> |
||||
|
@ -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": [] |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue