ihzero 2024-04-24 16:04:38 +08:00
commit 19a98f563a
5 changed files with 7482 additions and 217 deletions

7268
pnpm-lock.yaml 100644

File diff suppressed because it is too large Load Diff

View File

@ -15,48 +15,35 @@
:scrollable="false"
lineColor="#ee2c37"
:list="tabList"
:current="tabIndex"
@change="tabChange"
></uv-tabs>
</uv-sticky>
<mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback">
<view class="px-base space-y-20rpx mt-30rpx">
<view
v-for="item in list"
:key="item.id"
class="card-shadow bg-white rounded-19rpx p-base space-y-10rpx"
>
<view class="flex items-center justify-between">
<view class="text-30rpx"> {{ item.type.name }} </view>
<view
:style="[
{
color: statusFun(
item.workflow_check.check_status,
'statusExpense',
'color'
),
},
]"
class="text-24rpx"
>{{ item.workflow_check.check_status_text }}</view
>
</view>
<view class="text-24rpx text-hex-999999 flex">
<view class="w-140rpx">报销金额</view>
<view class="text-primary">{{ item.expense }}</view>
</view>
<view class="text-24rpx text-hex-999999 flex">
<view class="w-140rpx">报销时间</view>
<view class="text-hex-333">{{ timeFormat(item.created_at) }}</view>
</view>
<view class="text-24rpx text-hex-999999">
<view class="">
<text class="w-140rpx inline-block">报销原因:</text>
<text class="text-hex-333 leading-27rpx">{{ item.reason }}</text>
</view>
</view>
</view>
</view>
</mescroll-body>
<view class="px-base space-y-20rpx mt-30rpx">
<MescrollItem
ref="mescrollItem0"
:top="88"
:i="0"
:index="tabIndex"
:apiUrl="tabList[0].apiUrl"
>
<template v-slot="{ list }">
<Item v-for="item in list" :key="item.id" :item="item" @click="detail" />
</template>
</MescrollItem>
<MescrollItem
ref="mescrollItem1"
:i="1"
:top="88"
:index="tabIndex"
:apiUrl="tabList[1].apiUrl"
:params="tabList[1].params"
>
<template v-slot="{ list }">
<Item v-for="item in list" :key="item.id" :item="item" @click="checkDetail" />
</template>
</MescrollItem>
</view>
</view>
</template>
<script setup>
@ -65,44 +52,37 @@ import { http } from '@/utils/request'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import useMescroll from '@/uni_modules/mescroll-uni/hooks/useMescroll.js'
import useMescrollMore from '@/uni_modules/mescroll-uni/hooks/useMescrollMore.js'
import { timeFormat } from '@climblee/uv-ui/libs/function'
import statusFun from '@/utils/status'
const { mescrollInit, downCallback, getMescroll } = useMescroll(
import MescrollItem from '@/components/mescroll-api/more.vue'
import Item from './item.vue'
const mescrollItem0 = ref(null)
const mescrollItem1 = ref(null)
const mescrollItems = [mescrollItem0, mescrollItem1]
const { tabIndex, getMescroll, scrollToLastY } = useMescrollMore(
mescrollItems,
onPageScroll,
onReachBottom
)
const list = ref([])
const tabList = ref([
{
name: '我的报销',
apiUrl: '/reimbursements',
},
{
name: '报销审核',
apiUrl: '/workflow',
params: { subject_type: 'reimbursements', include: 'employee,type' }
},
])
const upCallback = async (mescroll) => {
const { size, num } = mescroll
try {
const resData = await http.get('/reimbursements', {
params: {
per_page: size,
page: num,
},
})
const curPageData = resData || []
if (num === 1) list.value = []
list.value = list.value.concat(curPageData)
mescroll.endSuccess(curPageData.length)
} catch (error) {
console.log(error)
mescroll.endErr() // ,
} finally {
// firstloading.value = false
}
const tabChange = ({ index }) => {
tabIndex.value = index
scrollToLastY()
}
const goPath = (url) => {
@ -110,4 +90,13 @@ const goPath = (url) => {
url,
})
}
//
const detail = (item) => {
console.log(item.id)
}
//
const checkDetail = (item) => {
console.log(item.id)
}
</script>

View File

@ -0,0 +1,43 @@
<template>
<view class="card-shadow bg-white rounded-19rpx p-base space-y-10rpx" @click="detail(item)">
<view class="flex items-center justify-between">
<view class="text-30rpx"> {{ item.type?.name }} </view>
<view :style="[
{
color: statusFun(
item.workflow_check?.check_status,
'statusExpense',
'color'
),
},
]" class="text-24rpx">{{ item.workflow_check?.check_status_text }}</view>
</view>
<view class="text-24rpx text-hex-999999 flex">
<view class="w-140rpx">报销金额</view>
<view class="text-primary">{{ item.expense }}</view>
</view>
<view class="text-24rpx text-hex-999999 flex">
<view class="w-140rpx">报销时间</view>
<view class="text-hex-333">{{ timeFormat(item.created_at) }}</view>
</view>
<view class="text-24rpx text-hex-999999">
<view class="">
<text class="w-140rpx inline-block">报销原因:</text>
<text class="text-hex-333 leading-27rpx">{{ item.reason }}</text>
</view>
</view>
</view>
</template>
<script setup>
import { timeFormat } from '@climblee/uv-ui/libs/function'
import statusFun from '@/utils/status'
const emits = defineEmits(['click'])
const props = defineProps({
item: Object,
})
const detail = (item) => {
emits('click', item)
}
</script>

View File

@ -2,16 +2,16 @@
<view>
<uv-sticky bgColor="#fff">
<view class="flex-center h-44px">
<view class="flex-center flex-1" @click="selectMenu({ name: 'shore' })">
<view>全部区域</view>
<view class="flex-center flex-1" @click="openCity">
<view>{{ selected.area_text }}</view>
<uv-icon
class="ml-10rpx"
size="20rpx"
name="arrow-down-fill"
></uv-icon>
</view>
<view class="flex-center flex-1" @click="selectMenu({ name: 'store' })">
<view>全部区域</view>
<view class="flex-center flex-1" @click="openStore">
<view>{{ selected.store_text }}</view>
<uv-icon
class="ml-10rpx"
size="20rpx"
@ -21,173 +21,138 @@
</view>
</uv-sticky>
<uv-picker
ref="shoreRef"
ref="cityRef"
keyName="name"
@change="shoreChange"
:columns="shoreList"
@confirm="shoreConfirm"
></uv-picker>
:columns="cityList"
:loading="cityLoading"
cancelText="重置"
@confirm="cityConfirm"
@change="cityChange"
@cancel="cityReset"
/>
<uv-picker
ref="storeRef"
keyName="address"
@change="shoreChange"
keyName="title"
:columns="storeList"
@confirm="shoreConfirm"
:loading="storeLoading"
@confirm="storeConfirm"
></uv-picker>
</view>
</template>
<script>
import { http } from '@/utils/request'
import data from './da.json'
export default {
onPageScroll() {
//
// this.$refs.dropDown.init()
},
computed: {
dropItem(name) {
return (name) => {
return {
label: name,
value: name,
}
}
},
//
currentDropItem() {
return this[this.activeName]
},
},
name: 'StoreDropDown',
data() {
return {
shoreList: [],
cityData: {},
// {province: {code, name}, city: {code, name}, area_text: '', store: {id, name}, store_text: ''}
selected: {
area_text: '全部区域',
store_text: '全部门店',
},
cityLoading: false,
cityList: [],
storeLoading: false,
storeList: [],
// value
defaultValue: [0, 'all'],
//
result: [],
activeName: 'shore',
shore: {
label: '全部区域',
activeIndex: [0, 0],
color: '#333',
activeColor: '#2878ff',
},
store: {
label: '全部门店',
activeIndex: 0,
color: '#333',
activeColor: '#2878ff',
},
cityData: data,
}
},
created() {
this.init()
},
methods: {
async init() {
const province = this.cityData.province
this.shoreList = [
province,
this.getCityByProvince(province[this.shore.activeIndex[1]].code),
]
},
change(e) {
console.log('弹窗打开状态:', e)
},
/**
* 点击每个筛选项回调
* @param {Object} e { name, active, type } = e
*/
selectMenu(e) {
const { name } = e
this.activeName = name
if (name === 'shore') {
const active = this.shore.activeIndex
const list = this.getCityByProvince(this.shoreList[0][active[0]].code)
this.shoreList[1] = list
this.$refs.shoreRef.setColumnValues(1, list)
this.$refs.shoreRef.setIndexs(active, true)
this.$refs.shoreRef.open()
}
if (name === 'store') {
this.$refs.storeRef.open()
}
},
/**
* 点击菜单回调处理
* @param {Object} item 选中项 { label,value } = e
*/
clickItem(e) {},
shoreChange(e) {
const { columnIndex, index } = e
if (columnIndex == 0) {
const item = this.shoreList[columnIndex][index]
this.shoreList[1] = this.getCityByProvince(item.code)
this.$refs.shoreRef.setColumnValues(
1,
this.getCityByProvince(item.code)
)
}
},
shoreConfirm(e) {
this.shore.activeIndex = e.indexs
const item = {
name: 'shore',
}
const cityIndex = this.shore.activeIndex[1]
const index = cityIndex == 0 ? 0 : 1
const index2 = e.indexs[index]
},
getCityByProvince(province) {
return [
{
name: '全部',
code: 'all',
},
].concat(this.cityData.city[province])
},
getStoreByCity(city) {
const res = http.get('/auth/stores', {
params: {
city: city,
},
init() {
this.cityLoading = true
http.get('/region').then(res => {
this.cityLoading = false
this.cityData = res
const firstProvince = this.cityData.province[0]
this.cityList = [
this.cityData.province,
this.findCityByProvince(firstProvince.code)
]
this.findStoreList()
}).catch(error => {
this.cityLoading = false
})
this.storeList = [
{
id: 1,
title: '1',
master_id: 1,
category_id: 'store_category_1_1',
business_id: 'store_business_1',
level_id: 'store_level_2',
region: {
city: '天津市市辖区',
code: 120100,
street: null,
cityCode: 120100,
district: null,
province: '天津市',
districtCode: 0,
provinceCode: 120000,
},
address: '回龙观(地铁站)',
lon: '116.34266369754',
lat: '40.076418413591',
profit_ratio: 0,
profit_money: '0.00',
business_status: 1,
created_at: '2024-04-03 17:17:02',
updated_at: '2024-04-03 17:17:02',
business_status_text: '开业',
business_status_color: 'success',
},
]
},
},
findStoreList() {
const params = {}
if (this.selected.province) {
params.province_code = this.selected.province.code
}
if (this.selected.city) {
params.city_code = this.selected.city.code
}
this.storeLoading = true
http.get('/auth/stores', { params }).then(res => {
this.storeLoading = false
res.unshift({title: '全部门店', id: 'all'})
this.storeList = [res]
}).catch(error => {
this.storeLoading = false
})
},
loadData() {
console.log('加载数据....', this.selected)
this.$emit('refresh', this.selected)
},
openCity() {
this.$refs.cityRef.open()
},
cityReset() {
this.selected = { area_text: '全部区域', store_text: '全部门店' }
this.loadData()
},
cityConfirm(e) {
const province = e.value[0]
const city = e.value[1]
if (province && city) {
if (province.code != 'all') {
this.selected.province = province
}
if (city.code != 'all') {
this.selected.city = city
}
this.selected.area_text = city.code == 'all' ? province.name : city.name
this.storeReset()
this.findStoreList()
this.loadData()
}
},
cityChange(e) {
const { columnIndex , index} = e
if (columnIndex == 0) {
const province = this.cityData.province[index]
this.$refs.cityRef.setColumnValues(1, this.findCityByProvince(province.code))
}
},
openStore() {
this.$refs.storeRef.open()
},
storeConfirm(e) {
const store = e.value[0]
if (store) {
if (store.id != 'all') {
this.selected.store = store
}
this.selected.store_text = store.title
this.loadData()
}
},
storeReset() {
this.selected.store_text = '全部门店'
this.selected.store = null
},
findCityByProvince(provinceCode) {
const cityList = this.cityData.city[provinceCode]
if (cityList.length > 1 && cityList[0].code != 'all') {
cityList.unshift({name: '全部', code: 'all'})
}
return cityList
}
}
}
</script>

View File

@ -50,11 +50,11 @@ const form = ref({
const handleClick = async () => {
try {
// const { username, password } = form.value
// await userStore.login({
// username,
// password,
// })
const { username, password } = form.value
await userStore.login({
username,
password,
})
uni.switchTab({
url: '/pages/home/index',
})