fix:更新优化

This commit is contained in:
Your Name 2026-05-27 14:49:38 +08:00
parent aef8c8b909
commit 6a7e01c0bf
64 changed files with 4653 additions and 157 deletions

View File

@ -1,5 +1,5 @@
NODE_ENV= development
VITE_HTTP_BASE_URL = http://10.39.13.78:8002/api/
# VITE_HTTP_BASE_URL = https://test-weapp-api.linyikj.com.cn/api/
# VITE_HTTP_BASE_URL = http://test-weapp-api.linyikj.com.cn/api/
# VITE_HTTP_BASE_URL = https://weapp-api.linyikj.com.cn/api/
VITE_ACCESS_TOKEN_KEY= 'ACCESS_TOKEN_CUSTOMER'

View File

@ -1,3 +1,3 @@
{
"version": "0.0.95"
"version": "0.0.108"
}

View File

@ -1,5 +1,5 @@
{
"url": "http://10.39.13.78:8001/api/docs/openapi",
"url": "http://10.39.13.78:8002/api/docs/openapi",
"module": "Customer",
"outPath": "./src/gen/",
"apis": {

View File

@ -8,6 +8,7 @@ const auth = useWeAppAuthStore()
const globalData = {
//
selectProject: {},
address_city:"",
//
selectedOrg: {},
selectedIndex: 0,
@ -17,12 +18,16 @@ const globalData = {
onLaunch(async () => {
const app = getCurrentInstance()
await auth.login(app)
auth.SetAddressCity()
console.log('App Launch')
//
// #ifdef MP-WEIXIN
CheckUpdate()
// #endif
})
onShow(() => {})
onHide(() => {
console.log('App Hide')

View File

@ -0,0 +1,102 @@
<template>
<view class="city-selector">
<!-- 搜索栏 -->
<view class="search-bar">
<view class="search-input-wrapper">
<u-search placeholder="搜索城市" shape="round" :clearabled="true" :showAction="false" @input="method.onSearchInput" v-model="useModel.searchKeyword.value"></u-search>
</view>
</view>
<!-- 搜索结果 -->
<view v-if="useModel.searchKeyword.value && useModel.searchResults.value.length > 0" class="search-results">
<scroll-view scroll-y class="results-scroll">
<view
v-for="(city, index) in useModel.searchResults.value"
:key="`search_${index}`"
class="city-item"
@click="method.selectCity(city)"
>
<view class="city-name">{{ city.city }}</view>
<!-- <view v-if="city.pinyin" class="city-pinyin">{{ city.pinyin }}</view> -->
</view>
</scroll-view>
</view>
<!-- 空搜索结果 -->
<view v-else-if="useModel.searchKeyword.value && useModel.searchResults.value.length === 0" class="empty-result">
<hs-empty text="未找到相关城市" />
</view>
<!-- 城市列表 -->
<view v-else class="city-list-container">
<scroll-view scroll-y class="city-scroll" scroll-with-animation :scroll-into-view="useModel.scrollToId.value">
<!-- 当前定位城市 -->
<view v-if="useModel.currentCity.value" class="city-section">
<view class="section-title">当前定位</view>
<view class="city-item current-city" @click="method.selectCity(useModel.currentCity.value)">
<u-icon name="map" size="14"></u-icon>
<view class="city-name">{{ useModel.currentCity.value.name }}</view>
</view>
</view>
<!-- 热门城市 -->
<view v-if="useModel.hotCities.value.length > 0" class="city-section">
<view class="section-title">已开通城市</view>
<view class="hot-cities-grid">
<view
v-for="(city, index) in useModel.openCities.value"
:key="`hot_${index}`"
class="hot-city-item"
@click="method.selectCity(city)"
>
{{ city.city }}
</view>
</view>
</view>
<!-- 所有城市按字母分组 -->
<!-- <view v-for="(group, letter) in useModel.cityGroups.value" :key="letter" class="city-section" :id="`section_${letter}`">
<view class="section-title">{{ letter }}</view>
<view
v-for="(city, index) in group"
:key="`city_${letter}_${index}`"
class="city-item"
@click="method.selectCity(city)"
>
<view class="city-name">{{ city.name }}</view>
</view>
</view> -->
</scroll-view>
<!-- 右侧字母索引 -->
<!-- <view v-if="useModel.indexLetters.value.length > 0" class="index-bar">
<view
v-for="(letter, index) in useModel.indexLetters.value"
:key="`index_${index}`"
class="index-item"
@click="method.scrollToSection(letter)"
>
{{ letter }}
</view>
</view> -->
</view>
</view>
</template>
<script setup lang="ts">
import { useWeAppAuthStore } from '@/common'
const auth = useWeAppAuthStore()
import { onLoad } from '@dcloudio/uni-app'
import method from './method'
import useModel from './model'
onLoad(() => {
useModel.currentCity.value = { name: auth?.data?.current_city?.city || '深圳' }
// method.getLocation()
//
method.getCityList()
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,85 @@
import useModel, { City } from './model'
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import { useWeAppAuthStore } from '@/common'
import config from '@/common/libraries/config'
const auth = useWeAppAuthStore()
/**
*
*/
const onSearchInput = (e: any) => {
useModel.searchKeyword.value = e.detail.value
}
/**
*
*/
const clearSearch = () => {
useModel.searchKeyword.value = ''
}
/**
*
*/
const selectCity = (city: City) => {
console.log('选择城市:', city)
// TODO: 返回上一页并传递选中的城市
// 可以通过事件总线或 uni.$emit 传递数据
auth.data.address_city = {city: city?.name || '',...city}
// uni.$emit('citySelected', city)
uni.navigateBack({
delta: 1
})
}
/**
*
*/
const scrollToSection = (letter: string) => {
useModel.scrollToId.value = `section_${letter}`
}
/**
*
*/
const getLocation = () => {
// TODO: 实际项目中调用定位API
uni.getLocation({
type: 'wgs84',
success: (res) => {
console.log('当前位置:', res)
// 根据经纬度获取城市名称
// 可以调用逆地理编码API获取城市信息
// currentCity.value = { name: '深圳', pinyin: 'shenzhen', code: '440300' }
},
fail: (err) => {
console.log('获取定位失败:', err)
uni.showToast({
title: '获取定位失败',
icon: 'none'
})
}
})
}
/**
*
*/
const getCityList = () => {
// TODO: 调用接口获取城市列表
// const res = await Apis.City.List()
// useModel.allCities.value = res.data
getApiLoading(Apis.Asset.AssetHouses.GetCities, {app_id: config?.WxAppId}).then(res => {
useModel.openCities.value = res.data || []
console.log(res)
})
}
export default {
onSearchInput,
clearSearch,
selectCity,
scrollToSection,
getLocation,
getCityList
}

View File

@ -0,0 +1,144 @@
import { ref, computed } from 'vue'
// 城市数据类型
export interface City {
name?: string
pinyin?: string
code?: string
city?: string
city_id?: number
}
// 搜索关键词
export const searchKeyword = ref('')
// 当前定位城市
export const currentCity = ref<City | null>(null)
// 滚动定位ID
export const scrollToId = ref('')
// 热门城市列表
export const hotCities = ref<City[]>([
{ name: '北京', pinyin: 'beijing', code: '110000' },
{ name: '上海', pinyin: 'shanghai', code: '310000' },
{ name: '广州', pinyin: 'guangzhou', code: '440100' },
{ name: '深圳', pinyin: 'shenzhen', code: '440300' },
{ name: '杭州', pinyin: 'hangzhou', code: '330100' },
{ name: '成都', pinyin: 'chengdu', code: '510100' },
{ name: '重庆', pinyin: 'chongqing', code: '500000' },
{ name: '武汉', pinyin: 'wuhan', code: '420100' }
])
//已开通城市
export const openCities = ref<City[]>([])
// 所有城市数据(示例数据,实际应从接口获取)
export const allCities = ref<City[]>([
// A-G
{ name: '安庆', pinyin: 'anqing' },
{ name: '蚌埠', pinyin: 'bengbu' },
{ name: '包头', pinyin: 'baotou' },
{ name: '北京', pinyin: 'beijing', code: '110000' },
{ name: '常州', pinyin: 'changzhou' },
{ name: '成都', pinyin: 'chengdu', code: '510100' },
{ name: '重庆', pinyin: 'chongqing', code: '500000' },
{ name: '大连', pinyin: 'dalian' },
{ name: '东莞', pinyin: 'dongguan' },
// F
{ name: '佛山', pinyin: 'foshan' },
{ name: '福州', pinyin: 'fuzhou' },
// G
{ name: '广州', pinyin: 'guangzhou', code: '440100' },
{ name: '贵阳', pinyin: 'guiyang' },
// H
{ name: '杭州', pinyin: 'hangzhou', code: '330100' },
{ name: '哈尔滨', pinyin: 'haerbin' },
{ name: '合肥', pinyin: 'hefei' },
{ name: '湖州', pinyin: 'huzhou' },
// J
{ name: '嘉兴', pinyin: 'jiaxing' },
{ name: '金华', pinyin: 'jinhua' },
{ name: '济南', pinyin: 'jinan' },
// K
{ name: '昆明', pinyin: 'kunming' },
// L
{ name: '兰州', pinyin: 'lanzhou' },
// N
{ name: '南昌', pinyin: 'nanchang' },
{ name: '南京', pinyin: 'nanjing' },
{ name: '南宁', pinyin: 'nanning' },
{ name: '宁波', pinyin: 'ningbo' },
// Q
{ name: '青岛', pinyin: 'qingdao' },
// S
{ name: '上海', pinyin: 'shanghai', code: '310000' },
{ name: '深圳', pinyin: 'shenzhen', code: '440300' },
{ name: '沈阳', pinyin: 'shenyang' },
{ name: '石家庄', pinyin: 'shijiazhuang' },
{ name: '苏州', pinyin: 'suzhou' },
// T
{ name: '唐山', pinyin: 'tangshan' },
{ name: '天津', pinyin: 'tianjin' },
// W
{ name: '潍坊', pinyin: 'weifang' },
{ name: '温州', pinyin: 'wenzhou' },
{ name: '武汉', pinyin: 'wuhan', code: '420100' },
{ name: '无锡', pinyin: 'wuxi' },
// X
{ name: '厦门', pinyin: 'xiamen' },
{ name: '西安', pinyin: 'xian' },
// Y
{ name: '烟台', pinyin: 'yantai' },
{ name: '扬州', pinyin: 'yangzhou' },
{ name: '宜昌', pinyin: 'yichang' },
// Z
{ name: '郑州', pinyin: 'zhengzhou' },
{ name: '珠海', pinyin: 'zhuhai' }
])
// 搜索结果
export const searchResults = computed(() => {
if (!searchKeyword.value) return []
const keyword = searchKeyword.value.toLowerCase()
return openCities.value.filter((city:any) => {
return city.city?.includes(keyword)
})
})
// 索引字母列表
export const indexLetters = computed(() => {
return Object.keys(cityGroups.value).sort()
})
// 城市按首字母分组
export const cityGroups = computed(() => {
const groups: Record<string, City[]> = {}
allCities.value.forEach((city:any) => {
const letter = getPinyinFirstLetter(city?.pinyin || city?.name)
if (!groups[letter]) {
groups[letter] = []
}
groups[letter].push(city)
})
return groups
})
// 获取拼音首字母(简化版,实际应使用拼音库)
const getPinyinFirstLetter = (str: string) => {
const firstChar = str.charAt(0).toUpperCase()
return firstChar
}
export default {
searchKeyword,
currentCity,
scrollToId,
hotCities,
allCities,
searchResults,
indexLetters,
cityGroups,
openCities
}

View File

@ -0,0 +1,202 @@
.city-selector {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f5f5f5;
// 搜索栏
.search-bar {
background-color: #fff;
padding: 20rpx 30rpx;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
.search-input-wrapper {
display: flex;
align-items: center;
.search-icon {
width: 32rpx;
height: 32rpx;
margin-right: 16rpx;
}
.search-input {
flex: 1;
font-size: 28rpx;
color: #333;
height: 100%;
}
.search-placeholder {
color: #999;
}
.clear-icon {
width: 32rpx;
height: 32rpx;
margin-left: 16rpx;
}
}
}
// 搜索结果
.search-results {
flex: 1;
overflow: hidden;
background-color: #fff;
.results-scroll {
height: 100%;
}
}
// 空状态
.empty-result {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60rpx 0;
.empty-icon {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
opacity: 0.5;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
}
// 城市列表容器
.city-list-container {
flex: 1;
display: flex;
position: relative;
overflow: hidden;
.city-scroll {
flex: 1;
height: 100%;
}
// 右侧字母索引
.index-bar {
position: absolute;
right: 10rpx;
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
align-items: center;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 40rpx;
padding: 20rpx 10rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
.index-item {
font-size: 22rpx;
color: #666;
padding: 6rpx 10rpx;
font-weight: 500;
}
}
}
// 城市分组
.city-section {
background-color: #fff;
margin-bottom: 20rpx;
.section-title {
padding: 20rpx 30rpx;
font-size: 26rpx;
color: #999;
background-color: #f5f5f5;
font-weight: 500;
}
}
// 当前定位城市
.current-city {
display: flex;
align-items: center;
padding: 30rpx;
.location-icon {
width: 32rpx;
height: 32rpx;
margin-right: 16rpx;
}
.city-name {
color: #0082FA;
padding-left:5rpx;
}
}
// 热门城市网格
.hot-cities-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
padding: 20rpx 30rpx 30rpx;
.hot-city-item {
display: flex;
align-items: center;
justify-content: center;
height: 72rpx;
background-color: #f5f5f5;
border-radius: 12rpx;
font-size: 28rpx;
color: #333;
text-align: center;
padding: 0 10rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:active {
background-color: #e8e8e8;
}
}
}
// 城市列表项
.city-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
transition: background-color 0.2s;
&:last-child {
border-bottom: none;
}
&:active {
background-color: #f8f8f8;
}
.city-name {
font-size: 30rpx;
color: #333;
flex: 1;
}
.city-pinyin {
font-size: 24rpx;
color: #999;
margin-left: 20rpx;
}
}
}

View File

@ -0,0 +1,47 @@
<template>
<view>
<view class="card_form">
<hs-cell
title="房屋信息"
required
borderTop
isLink
:value="useModel?.formData?.value?.full_name"
@click="method?.handleToSelectHouse"
/>
<hs-cell title="装修类型" borderTop required>
<hs-radio
:Enums="RenovationAppliesTypeEnum"
v-model:valueModel="useModel.formData.value.type"
required
/>
</hs-cell>
<hs-cell title="办理类型" borderTop required>
<hs-radio
:Enums="RenovationAppliesProcessTypeEnum"
v-model:valueModel="useModel.formData.value.process_type"
required
/>
</hs-cell>
</view>
<hs-footer btnParimaryName="下一步" @handleParmaryClick="method.handleSubmit" />
</view>
</template>
<script setup lang="ts">
import { onShow, onUnload } from '@dcloudio/uni-app'
import method from './method'
import useModel from './model'
import { RenovationAppliesTypeEnum, RenovationAppliesProcessTypeEnum } from '@/gen/Enums'
onShow(() => {
method?.init()
})
onUnload(() => {
useModel.formData.value = {}
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,71 @@
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import userLoginStatus from '@/common/libraries/userUserLogin'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
import { useWeAppAuthStore, useWorkStore } from '@/common'
import useModel from './model'
const work = useWorkStore()
const auth = useWeAppAuthStore()
const getList = () => {
getApiLoading(Apis.Activity.ActivityEnrolls.List, useModel?.formData?.value).then(res => {
useModel.listData.value = [...useModel.listData.value, ...res.data]
useModel.metaData.value = res.meta
console.log(res)
})
}
export default {
getList,
init() {
if (work?.selectWorkHouse?.asset_house) {
useModel.formData.value = {
...useModel.formData.value,
asset_houses_id: work?.selectWorkHouse?.asset_house?.id,
full_name: work?.selectWorkHouse?.asset_house?.full_name
}
} else {
useModel.formData.value = {
...useModel.formData.value,
asset_houses_id: auth?.data?.selected_house?.id,
full_name: auth?.data?.selected_house?.full_name
}
}
},
loadMore(page: number) {
useModel.formData.value.page = page
this.getList()
},
handleTabsChange(idx: number, res: any) {
useModel.currentTabs.value = idx
useModel.formData.value = {
page: 1,
status: res?.value
}
useModel.listData.value = []
getList()
console.log(idx, 'e')
},
handleToSelectHouse() {
uni.navigateTo({
url: '/INDEX/asset_houses/index?type=work_add'
})
},
handleSubmit() {
let data = useModel?.formData?.value
if (!data?.asset_houses_id) {
return showToast('请选择房屋!')
}
if (!data?.type) {
return showToast('请选择装修类型!')
}
if (!data?.process_type) {
return showToast('请选择办理类型!')
}
getApiLoading(Apis.Renovation.RenovationApplies.Store, useModel?.formData?.value).then(res => {
uni.redirectTo({
url: `/ME/decoration/update/index?id=${res.data.id}`
})
console.log(res)
})
}
}

View File

@ -0,0 +1,7 @@
import { reactive, ref } from 'vue'
export default {
listData: ref<any>([]),
formData: ref<any>({}),
metaData: ref({}),
currentTabs: ref(0)
}

View File

@ -0,0 +1,3 @@
page {
background-color: #f8f8f8;
}

View File

@ -0,0 +1,84 @@
<template>
<view class="add_worker_container">
<view class="form_card">
<view class="form_card_title"> <text></text> 申请人信息 </view>
<hs-cell title="姓名" required borderTop>
<hs-input v-model:valueModel="useModel.formData.value.worker_name" textAlign="right" />
</hs-cell>
<hs-cell title="手机号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.worker_phone"
maxLength="11"
textAlign="right"
/>
</hs-cell>
</view>
<view class="form_card">
<hs-radio-cell-picker
title="证件类型"
required
isLink
:Enums="HouseOccupantsCardTypeEnum"
v-model:valueModel="useModel.formData.value.card_type"
/>
<hs-cell title="证件号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.id_card"
maxLength="18"
textAlign="right"
/>
</hs-cell>
<hs-upload-id-card
required
borderTop
v-model:valueFrontModel="useModel.formData.value.card_front"
v-model:valueBackModel="useModel.formData.value.card_back"
/>
<hs-upload
title="工人照片"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.worker_photo"
/>
</view>
<view class="form_card">
<hs-date-picker
title="开始通行时间"
v-model:valueModel="useModel.formData.value.valid_from"
required
isLink
/>
<hs-date-picker
title="结束通行时间"
v-model:valueModel="useModel.formData.value.valid_to"
required
borderTop
isLink
/>
</view>
<hs-footer btnParimaryName="确定" @handleParmaryClick="method.handleSubmit" />
</view>
</template>
<script setup lang="ts">
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app'
import method from './method'
import useModel from './model'
import { HouseOccupantsCardTypeEnum } from '@/gen/Enums'
onShow(() => {
method.init()
})
onLoad((e: any) => {
useModel.formData.value.renovation_applies_id = e?.id
useModel.formData.value.type = e?.type
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,57 @@
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import userLoginStatus from '@/common/libraries/userUserLogin'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
import { useWeAppAuthStore, useWorkStore } from '@/common'
import useModel from './model'
const work = useWorkStore()
const auth = useWeAppAuthStore()
export default {
init() {
useModel.formData.value = {
...useModel.formData.value,
// worker_phone: auth?.data?.user?.phone || useModel.formData.value?.worker_phone || '',
worker_name: auth?.data?.user?.name || useModel.formData.value?.worker_name || ''
}
},
handleSubmit() {
let data = useModel?.formData?.value
if (!userLoginStatus?.onBindPhone()) {
return false
}
if (!data?.worker_name) {
return showToast('请设置工人姓名!')
}
if (!data?.worker_phone) {
return showToast('请设置工人手机号!')
}
if (!data?.card_type) {
return showToast('请选择工人证件类型!')
}
if (!data?.id_card) {
return showToast('请设置工人证件号!')
}
if (!data?.card_front?.length || !data?.card_back?.length) {
return showToast('请上传工人证件照片!')
}
if (!data?.worker_photo?.length) {
return showToast('请上传工人照片!')
}
if (!data?.valid_from || !data?.valid_to) {
return showToast('请设置通行有效期!')
}
getApiLoading(Apis.Renovation.RenovationWorkers.Store, useModel?.formData?.value).then(res => {
if (useModel?.formData?.value?.type === 'share') {
showToast('提交成功!', () => {
uni.switchTab({
url: '/pages/index/index'
})
})
} else {
showToastBack('提交成功!', 1, true)
}
console.log(res)
})
}
}

View File

@ -0,0 +1,7 @@
import { reactive, ref } from 'vue'
export default {
listData: ref<any>([]),
formData: ref<any>({}),
metaData: ref({}),
currentTabs: ref(0)
}

View File

@ -0,0 +1,7 @@
page {
background-color: #f8f8f8;
}
.add_worker_container {
padding-bottom: calc(130rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}

View File

@ -0,0 +1,60 @@
<template>
<hs-popup-buttom-custom
:show="props?.show"
title="提交验收"
@close="handleClose"
mode="bottom"
:closeable="true"
:round="20"
:safeAreaInsetBottom="false"
>
<view class="popup_content">
<hs-reservation-picker
title="期望上门时间"
required
v-model:valueDefault="popupFormData"
v-model:valueExpectStartTime="popupFormData.expect_start_time"
v-model:valueExpectEndTime="popupFormData.expect_end_time"
/>
<view class="popup_footer">
<hs-button label="提交" size="md" @click="handleSubmit" />
</view>
</view>
</hs-popup-buttom-custom>
</template>
<script setup lang="ts">
import { onHide } from '@dcloudio/uni-app'
import { ref, watch } from 'vue'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
const props = defineProps(['show', 'items'])
const emit = defineEmits(['click', 'handleSubmit', 'handleClose'])
const popupFormData = ref<any>({})
watch(
() => props?.show,
newVal => {
popupFormData.value = {}
}
)
const handleSubmit = () => {
if (!popupFormData.value?.expect_start_time) {
return showToast('请选择期望上门时间!')
}
emit('handleSubmit', { ...props?.items, ...popupFormData.value })
}
const handleClose = () => {
emit('handleClose')
}
onHide(() => {
handleClose()
})
</script>
<style lang="scss" scoped>
.popup_content {
padding: 30rpx;
.popup_footer {
padding: 30rpx 0 100rpx 0;
}
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<hs-popup-buttom-custom
:show="props?.show"
title="出入证延期"
@close="handleClose"
mode="bottom"
:closeable="true"
:round="20"
:safeAreaInsetBottom="false"
>
<view class="popup_content">
<hs-date-picker
title="开始时间"
v-model:valueModel="popupFormData.visit_start_time"
required
isLink
/>
<hs-cell title="原截止时间" borderTop> {{ props?.items?.valid_to }} </hs-cell>
<hs-date-picker
title="新截止时间"
v-model:valueModel="popupFormData.visit_end_time"
required
borderTop
isLink
/>
<view class="popup_footer">
<hs-button label="提交" size="md" @click="handleSubmit" />
</view>
</view>
</hs-popup-buttom-custom>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
const props = defineProps(['show', 'items'])
const emit = defineEmits(['click', 'handleSubmit', 'handleClose'])
const popupFormData = ref<any>({})
const handleSubmit = () => {
if (!popupFormData.value?.visit_end_time) {
return showToast('请选择新截止时间!')
}
emit('handleSubmit', { ...props?.items, ...popupFormData.value })
}
const handleClose = () => {
emit('handleClose')
}
watch(
() => props?.show,
newVal => {
popupFormData.value = {
...props?.items,
visit_start_time: props?.items?.valid_from || ''
// visit_end_time: props?.items?.valid_to || '',
}
console.log(popupFormData.value, props?.items, 'popupFormData.value')
}
)
</script>
<style lang="scss" scoped>
.popup_content {
padding: 30rpx;
.popup_footer {
padding: 30rpx 0 100rpx 0;
}
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<hs-popup-buttom-custom
:show="props?.show"
title="装修延期"
@close="handleClose"
mode="bottom"
:closeable="true"
:round="20"
:safeAreaInsetBottom="false"
:insetBottom="0"
>
<view class="popup_content">
<hs-cell title="原竣工结束时间"> {{ props?.items?.construction_end_date }} </hs-cell>
<hs-date-picker
title="新竣工结束时间"
v-model:valueModel="popupFormData.extension_date"
required
borderTop
isLink
/>
<view class="popup_footer">
<hs-button label="提交" size="md" @click="handleSubmit" />
</view>
</view>
</hs-popup-buttom-custom>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
const props = defineProps(['show', 'items'])
const emit = defineEmits(['click', 'handleSubmit', 'handleClose'])
const popupFormData = ref<any>({})
const handleSubmit = () => {
if (!popupFormData.value?.extension_date) {
return showToast('请选择新竣工结束时间!')
}
emit('handleSubmit', { ...props?.items, ...popupFormData.value })
}
const handleClose = () => {
emit('handleClose')
}
</script>
<style lang="scss" scoped>
.popup_content {
padding: 30rpx;
.popup_footer {
padding: 30rpx 0 100rpx 0;
}
}
</style>

View File

@ -0,0 +1,68 @@
<template>
<hs-popup-buttom-custom
:show="props?.show"
title="备案资料清单"
@close="handleClose"
mode="bottom"
:closeable="true"
:round="20"
>
<view class="popup_content">
<view class="popup_item_title"> 1产权人证件 </view>
<view class="popup_item_des"> ·需提供身份证正反面和证件号 </view>
<view class="popup_item_title"> 2房屋产权证明文件 </view>
<view class="popup_item_des"> ·可以为房产证购房发票交房合同等 </view>
<view class="group_item">
<view class="popup_item_title"> 3代理人身份证正反面有代理人的情况下 </view>
<view class="popup_item_title"> 4业主授权委托书有代理人的情况下 </view>
</view>
<view class="group_item">
<view class="popup_item_title"> 5施工方负责人身份证正反面装修公司承接时需要 </view>
<view class="popup_item_title"> 6装修公司营业执照装修公司承接时需要 </view>
<view class="popup_item_title"> 7装修公司资质证书装修公司承接时需要 </view>
<view class="popup_item_title"> 8装修公司授权委托书装修公司承接时需要 </view>
<view class="popup_item_title"> 9施工图纸如重大施工 </view>
<view class="popup_item_title"> 10装修公司承诺书装修公司承接时需要 </view>
</view>
<view class="group_item">
<view class="popup_item_title"> 11自装承诺书自装时需要 </view>
</view>
</view>
</hs-popup-buttom-custom>
</template>
<script setup lang="ts">
import { onHide } from '@dcloudio/uni-app'
const props = defineProps(['show', 'items'])
const emit = defineEmits(['click', 'handleSubmit', 'handleClose'])
const handleClose = () => {
emit('handleClose')
}
onHide(() => {
handleClose()
})
</script>
<style lang="scss" scoped>
.popup_content {
padding: 30rpx 40rpx;
.group_item {
border-top: 1rpx solid #eee;
padding: 30rpx 0;
}
.popup_item_title {
font-size: 28rpx;
font-weight: 500;
color: #3d3d3d;
}
.popup_item_des {
color: #999999;
font-size: 28rpx;
padding: 10rpx 0 20rpx 0;
}
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<hs-popup-buttom-custom
:show="props?.show"
title="请选择添加工人的方式"
@close="handleClose"
mode="bottom"
:closeable="true"
:round="20"
>
<view class="popup_content">
<template v-for="(i, index) in list" :key="`item_${index}`">
<view v-if="i?.type === 'page'" class="popup_content_item" @click="handleToPage(i)">
<view class="icon">
<image :src="i?.icon" mode="widthFix" />
</view>
<view class="label"> {{ i?.label }} </view>
<uni-icons type="right" size="15"></uni-icons>
</view>
<view v-if="i?.type === 'button'" class="popup_content_item" @click="handleToPage(i)">
<button open-type="share">
<view class="icon">
<image :src="i?.icon" mode="widthFix" />
</view>
<view class="label"> {{ i?.label }} </view>
<uni-icons type="right" size="15"></uni-icons>
</button>
</view>
</template>
</view>
</hs-popup-buttom-custom>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const props = defineProps(['show', 'items'])
const emit = defineEmits(['click', 'handleSubmit', 'handleClose'])
const handleClose = () => {
emit('handleClose')
}
const handleToPage = (i: { url?: string }) => {
uni.navigateTo({
url: `${i?.url || ''}?id=${props?.items?.id}`
})
}
const list = [
{
label: '自行添加',
icon: 'https://gc-test-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KA0DYY140XYWKJ8EA9V8PASV.png',
url: `/ME/decoration/add_worker/index`,
type: 'page'
},
{
label: '转发工人填写',
icon: 'https://gc-test-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KA0DW555P9YEXW0VY3SCA9F4.png',
type: 'button'
}
]
</script>
<style lang="scss" scoped>
.popup_content {
padding: 30rpx;
.popup_content_item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
background-color: #fff;
border-radius: 20rpx;
margin-bottom: 30rpx;
height: 140rpx;
font-size: 30rpx;
color: #3d3d3d;
button {
padding: 0;
margin: 0;
width: 100%;
background-color: transparent;
display: flex;
align-items: center;
justify-content: space-between;
height: 140rpx;
font-size: 30rpx;
color: #3d3d3d;
}
.icon {
width: 80rpx;
height: 80rpx;
}
image {
width: 80rpx;
height: 80rpx;
}
.label {
flex: 1;
padding: 0 25rpx;
text-align: left;
}
}
}
button:after {
border: none !important; /* 去掉边框 */
}
</style>

View File

@ -0,0 +1,168 @@
<template>
<view>
<view class="update_form_content">
<view class="form_card">
<view class="form_card_title"> <text></text> 施工方负责人信息 </view>
<hs-cell title="姓名" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.construction_principal_name"
textAlign="right"
/>
</hs-cell>
<hs-cell title="手机号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.construction_principal_phone"
maxLength="11"
textAlign="right"
/>
</hs-cell>
<hs-radio-cell-picker
title="证件类型"
required
borderTop
isLink
:Enums="HouseOccupantsCardTypeEnum"
v-model:valueModel="useModel.formData.value.construction_principal_card_type"
/>
<hs-cell title="证件号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.construction_principal_id_card"
maxLength="18"
textAlign="right"
/>
</hs-cell>
<hs-upload-id-card
required
borderTop
v-model:valueFrontModel="useModel.formData.value.construction_principal_id_card_front"
v-model:valueBackModel="useModel.formData.value.construction_principal_id_card_back"
/>
</view>
<view class="form_card" v-if="useModel?.formData?.value?.type === 'RenovationCompany'">
<view class="form_card_title"> <text></text> 施工公司信息 </view>
<!-- <hs-cell title="装修公司负责人名称" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.company_principal_name"
textAlign="right"
/>
</hs-cell>
<hs-cell title="装修公司负责人手机" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.company_principal_phone"
maxLength="11"
textAlign="right"
/>
</hs-cell> -->
<hs-cell title="装修公司全称" required borderTop>
<hs-input v-model:valueModel="useModel.formData.value.company_name" textAlign="right" />
</hs-cell>
<hs-cell title="社会统一信用代码" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.company_business_license_num"
textAlign="right"
/>
</hs-cell>
<hs-upload
title="营业执照照片"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.company_business_license"
/>
<hs-upload
title="资质证明"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.company_asset_certificate"
/>
<hs-upload
title="装修授权书"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.company_power_attorney"
/>
</view>
<view class="form_card">
<view class="form_card_title"> <text></text> 施工内容 </view>
<hs-date-picker
title="施工开始时间"
v-model:valueModel="useModel.formData.value.construction_start_date"
required
borderTop
isLink
/>
<hs-date-picker
title="施工结束时间"
v-model:valueModel="useModel.formData.value.construction_end_date"
required
borderTop
isLink
/>
<hs-cell title="装修内容" borderTop required>
<hs-radio
:Enums="RenovationAppliesRenovationContentEnum"
v-model:valueModel="useModel.formData.value.renovation_content"
required
/>
</hs-cell>
<view class="refund_info">
<view class="label"> 装修内容说明 </view>
<view class="refund_reason">
<textarea
v-model="useModel.formData.value.renovation_remark"
placeholder-style="color:#C9CDD4;font-size:28rpx;"
placeholder="请输入装修内容说明,例如:厨卫墙地砖拆除、安装衣柜、更换地板、客厅吊顶、全屋刷漆等"
/>
</view>
</view>
</view>
<view class="form_card">
<view class="form_card_title"> <text></text> 其他资料 </view>
<hs-upload
title="施工图"
:count="10"
:size="4"
borderTop
v-model:valueModel="useModel.formData.value.construction_draw"
/>
<hs-upload
title="装修承诺书"
:count="1"
:size="4"
borderTop
v-model:valueModel="useModel.formData.value.construction_commitment_letter"
/>
<hs-upload
title="其他附件"
:count="20"
:size="4"
borderTop
v-model:valueModel="useModel.formData.value.other_attachments"
/>
</view>
</view>
<hs-footer btnParimaryName="提交" @handleParmaryClick="method.handleNextSubmit" />
</view>
</template>
<script setup lang="ts">
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app'
import method from './method'
import useModel from './model'
import { HouseOccupantsCardTypeEnum, RenovationAppliesRenovationContentEnum } from '@/gen/Enums'
onLoad((e: any) => {
method?.getShow(e)
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,117 @@
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import userLoginStatus from '@/common/libraries/userUserLogin'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
import { useWeAppAuthStore, useWorkStore } from '@/common'
import useModel from './model'
const work = useWorkStore()
const auth = useWeAppAuthStore()
const handleSave = (type?: number) => {
// 暂存
getApiLoading(Apis.Renovation.RenovationApplies.Update, {
...useModel?.formData?.value,
is_deposit: useModel?.formData?.value?.is_deposit ? 1 : 0,
status: 'Draft'
}).then(res => {
if (type) {
showToast('提交成功!', () => {
uni.switchTab({
url: '/pages/index/index'
})
})
} else {
showToast('暂存成功!')
}
console.log(res)
})
}
export default {
init() {
if (work?.selectWorkHouse?.asset_house) {
useModel.formData.value = {
...useModel.formData.value,
asset_houses_id: work?.selectWorkHouse?.asset_house?.id,
full_name: work?.selectWorkHouse?.asset_house?.full_name
}
} else {
useModel.formData.value = {
...useModel.formData.value,
asset_houses_id: auth?.data?.selected_house?.id,
full_name: auth?.data?.selected_house?.full_name
}
}
},
getShow(res: { id: number }) {
getApiLoading(Apis.Renovation.RenovationApplies.Show, { id: res?.id }).then(res => {
useModel.showData.value = res?.data
useModel.formData.value = {
...res?.data,
is_deposit: res?.data?.is_deposit ? true : false
}
if (res?.data?.status !== 'Draft') {
showToast('当前装修申请已完成!', () => {
uni.switchTab({
url: '/pages/index/index'
})
})
}
console.log(res)
})
},
handleToSelectHouse() {
uni.navigateTo({
url: '/INDEX/asset_houses/index?type=work_add'
})
},
handleNextSubmit() {
let data = useModel?.formData?.value
if (!data?.construction_principal_name) {
return showToast('请输入施工负责人名称!')
}
if (!data?.construction_principal_phone) {
return showToast('请输入施工负责人手机号!')
}
if (!data?.construction_principal_card_type) {
return showToast('请选择施工负责人证件类型!')
}
if (!data?.construction_principal_id_card) {
return showToast('请输入施工负责人证件号!')
}
if (
!data?.construction_principal_id_card_front?.length ||
!data?.construction_principal_id_card_back?.length
) {
return showToast('请上传施工负责人证件!')
}
if (useModel?.formData?.value?.type === 'RenovationCompany') {
// if (!data?.company_principal_name || !data?.company_principal_phone) {
// return showToast('请输入装修公司负责人名称/手机号!')
// }
if (!data?.company_name) {
return showToast('请设置装修公司全称!')
}
if (!data?.company_business_license_num) {
return showToast('请输入社会统一信用代码!')
}
if (!data?.company_business_license?.length) {
return showToast('请上传装修公司营业执照!')
}
if (!data?.company_asset_certificate?.length) {
return showToast('请上传装修公司资质证明!')
}
if (!data?.company_power_attorney?.length) {
return showToast('请上传装修授权书!')
}
}
if (!data?.construction_start_date || !data?.construction_end_date) {
return showToast('请选择施工时间!')
}
if (!data?.renovation_content) {
return showToast('请选择装修内容!')
}
handleSave(1)
},
handleSave
}

View File

@ -0,0 +1,8 @@
import { reactive, ref } from 'vue'
export default {
listData: ref<any>([]),
formData: ref<any>({}),
metaData: ref({}),
current: ref(0),
showData: ref<any>({})
}

View File

@ -0,0 +1,77 @@
page {
background-color: #f8f8f8;
}
.share_card {
background: linear-gradient(180deg, #fff8f1 0%, #fff3e5 100%);
padding: 20rpx 30rpx;
color: #3d3d3d;
font-size: 26rpx;
display: flex;
align-items: center;
justify-content: space-between;
.share_btn {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #ff8f26;
color: #fff;
padding: 6rpx 25rpx;
border-radius: 100rpx;
}
}
.update_header {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #fff;
border-top: 1rpx solid #eee;
z-index: 100;
}
.update_form_content {
padding-bottom: calc(130rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}
.refund_info {
border-top: 1rpx solid #eee;
background-color: #fff;
padding: 30rpx 0;
.label {
font-size: 28rpx;
}
text {
color: #f00;
}
.refund_reason {
padding: 20rpx 0 0 0;
}
}
.footer_page {
display: flex;
align-items: center;
justify-content: space-between;
.previous_btn {
padding-right: 30rpx;
.label {
font-size: 20rpx;
color: #3d3d3d;
}
}
.group_btn_content {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
.next_btn {
flex: 1;
&:first-child {
padding-right: 30rpx;
}
}
}
}

View File

@ -0,0 +1,152 @@
<template>
<view class="decoration_list_page">
<cc-scroll-loading :meta="useModel?.metaData?.value" @load="method?.loadMore">
<view v-for="(i, index) in useModel?.listData?.value" :key="`item_${index}`" class="items">
<view class="header_items">
<view class="status_group">
<view :class="`items_status status_${i?.status}`">
{{
RenovationAppliesStatusEnum[i?.status as keyof typeof RenovationAppliesStatusEnum]
?.text
}}
</view>
<view
v-if="i?.status === 'Approved' && i?.construction_status !== 'CompletedConstruction'"
class="items_status status_default"
>
正常施工
</view>
<view
v-if="i?.status === 'Approved' && i?.construction_status === 'CompletedConstruction'"
class="items_status status_default"
>
已竣工
</view>
</view>
<view
v-if="i?.status !== 'Approved' && i?.status !== 'Pending'"
class="delete_btn"
@click="method?.handleDelete(i)"
>
<uni-icons type="trash" size="16"></uni-icons> 删除
</view>
</view>
<view class="content_items" @click="method.headleToGoShow(i)">
<view class="name">{{ i?.asset_house?.full_name }}</view>
<view class="decoration_info">
<view class="decoration_info_cell">
装修类型
<view class="value">
{{
RenovationAppliesTypeEnum[i?.type as keyof typeof RenovationAppliesTypeEnum]?.text
}}
</view>
</view>
<view class="decoration_info_cell">
创建时间
<view class="value">
{{ i?.created_at }}
</view>
</view>
<view class="decoration_info_cell" v-if="i?.construction_start_date">
施工时间
<view class="value">
{{ i?.construction_start_date || '-' }}{{ i?.construction_end_date || '-' }}
</view>
</view>
</view>
</view>
<view v-if="i?.status !== 'Pending'" class="footer_items">
<template v-if="i?.status === 'Draft' || i?.status === 'Rejected'">
<hs-button
:label="i?.status === 'Rejected' ? '重新编辑' : '继续编辑'"
type="ghost"
@click="method.handleToPage(`/ME/decoration/update/index?id=${i?.id}`)"
/>
</template>
<template v-if="i?.status === 'Approved'">
<hs-button
label="添加工人"
type="ghost"
@click="method?.handleToPage(`/ME/decoration/add_worker/index?id=${i?.id}`)"
/>
<view class="nth_btn" v-if="!i?.house_work_orders?.length">
<hs-button label="申请验收" type="ghost" @click="method.handleAcceptance(i)" />
</view>
<view class="nth_btn">
<hs-button label="装修延期" type="ghost" @click="method.handleExtension(i)" />
</view>
</template>
</view>
</view>
</cc-scroll-loading>
<hs-footer>
<view class="footer_page">
<view class="filing_btn" @click="useModel.showFiling.value = true">
<view class="icon">
<u-icon name="order" size="24"></u-icon>
</view>
<view class="label"> 备案清单 </view>
</view>
<view class="footer_group_btn">
<hs-button label="开始登记" @click="method.toPageAdd" type="primary" size="md" />
</view>
</view>
</hs-footer>
<MyPopupAcceptance
:items="useModel?.popupFormData?.value"
:show="useModel?.showPopupAcceptance?.value"
@handleClose="handleClose"
@handleSubmit="method.handleAcceptanceSubmit"
/>
<MyPopupExtension
:items="useModel?.popupFormData?.value"
:show="useModel?.showPopupExtension?.value"
@handleClose="handleClose"
@handleSubmit="method.handleExtensionSubmit"
/>
<MyPopupFilingList :show="useModel?.showFiling?.value" @handleClose="handleClose" />
</view>
</template>
<script setup lang="ts">
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app'
import MyPopupAcceptance from '../components/PopupAcceptance.vue'
import MyPopupFilingList from '../components/PopupFilingList.vue'
import method from './method'
import useModel from './model'
import MyPopupExtension from '../components/PopupExtension.vue'
import { RenovationAppliesStatusEnum, RenovationAppliesTypeEnum } from '@/gen/Enums'
onLoad(() => {
useModel.listData.value = []
method?.getList()
})
onShow(() => {
if (useModel?.loadMore?.value) {
useModel.formData.value.page = 1
useModel.listData.value = []
method?.getList()
}
})
const handleClose = () => {
useModel.showPopupExtension.value = false
useModel.showPopupAcceptance.value = false
useModel.showFiling.value = false
}
onUnload(() => {
useModel.loadMore.value = false
useModel.formData.value.page = 1
useModel.listData.value = []
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,93 @@
import { Apis } from '@/gen/Apis'
import useModel from './model'
import { useWeAppAuthStore } from '@/common'
import { getApiLoading } from '@/common/libraries/apiLoading'
import userLoginStatus from '@/common/libraries/userUserLogin'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
const auth = useWeAppAuthStore()
const getList = () => {
getApiLoading(Apis.Renovation.RenovationApplies.List, useModel?.formData?.value).then(res => {
useModel.listData.value = [...useModel.listData.value, ...res.data]
useModel.metaData.value = res.meta
useModel.loadMore.value = true
console.log(res)
})
}
const handleLoadList = () => {
useModel.formData.value.page = 1
useModel.listData.value = []
getList()
}
export default {
getList,
loadMore(page: number) {
useModel.formData.value.page = page
this.getList()
},
headleToGoShow(e: { id: string; status: string }) {
if (e?.status === 'Approved') {
uni.navigateTo({
url: `/ME/decoration/show/index?id=${e?.id}`
})
}
},
toPageAdd() {
uni.navigateTo({
url: '/ME/decoration/add/index'
})
},
handleToPage(url: string) {
uni.navigateTo({
url: url
})
},
handleAcceptanceSubmit(data?: any) {
getApiLoading(Apis.Renovation.RenovationApplies.ApplyAccept, data).then(res => {
showToast('提交成功!', () => {
useModel.showPopupAcceptance.value = false
handleLoadList()
})
console.log(res)
})
},
handleExtensionSubmit(data?: any) {
getApiLoading(Apis.Renovation.RenovationApplies.ApplyExtension, data).then(res => {
showToast('提交成功!', () => {
useModel.showPopupExtension.value = false
handleLoadList()
})
console.log(res)
})
},
handleAcceptance(res: any) {
useModel.popupFormData.value = { id: res?.id }
useModel.showPopupAcceptance.value = true
},
handleExtension(res: any) {
useModel.popupFormData.value = res
useModel.showPopupExtension.value = true
console.log(res)
},
handleDelete(data: { id: string }) {
uni.showModal({
title: '提示',
content: '确定要删除?不可恢复!',
success: function (res) {
if (res.confirm) {
getApiLoading(Apis.Renovation.RenovationApplies.SoftDelete, data).then(res => {
showToast('删除成功!', () => {
handleLoadList()
})
console.log(res)
})
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
}

View File

@ -0,0 +1,13 @@
import { reactive, ref } from 'vue'
export default {
listData: ref<any>([]),
formData: ref({ page: 1 }),
metaData: ref({}),
currentTabs: ref(0),
popupFormData: ref<any>({}),
showPopup: ref(false),
showPopupExtension: ref(false),
showPopupAcceptance: ref(false),
showFiling: ref(false),
loadMore: ref(false)
}

View File

@ -0,0 +1,112 @@
page {
background-color: #f8f8f8;
}
.decoration_list_page {
padding-bottom: calc(130rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}
.items {
background-color: #fff;
margin: 30rpx 30rpx 0 30rpx;
padding: 0 30rpx;
border-radius: 20rpx;
.header_items {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
.status_group {
display: flex;
align-items: center;
}
.items_status {
padding: 7rpx 17rpx;
border-radius: 100rpx;
font-size: 24rpx;
background-color: #f3f3f4;
color: #909399;
}
.delete_btn {
color: #666666;
font-size: 28rpx;
display: flex;
align-items: center;
}
.status_Draft {
background-color: #edf4ff;
border: 1rpx solid #edf4ff;
color: #0082fa;
}
.status_Pending {
background-color: #fff7ed;
border: 1rpx solid #fff7ed;
color: #f97316;
}
.status_Approved {
background-color: #f0fdf4;
border: 1rpx solid #f0fdf4;
color: #22c55e;
}
.status_default {
border-radius: 100rpx;
border: 1rpx solid #c3c3c3;
color: #666666;
margin-left: 20rpx;
background-color: #fff;
}
}
.name {
color: #3d3d3d;
font-size: 32rpx;
font-weight: 500;
padding: 0 0 10rpx 0;
}
.decoration_info {
padding: 10rpx 0 30rpx 0;
&_cell {
display: flex;
align-items: center;
justify-content: space-between;
color: #666;
font-size: 28rpx;
padding-bottom: 20rpx;
.value {
color: #000;
}
&:last-child {
padding-bottom: 0;
}
}
}
.footer_items {
display: flex;
align-items: center;
justify-content: flex-end;
border-top: 1rpx solid #eee;
padding: 30rpx 0;
.nth_btn {
padding-left: 30rpx;
}
}
}
.footer_page {
display: flex;
align-items: center;
.filing_btn {
.icon {
display: flex;
justify-content: center;
width: 100%;
}
}
.label {
color: #3d3d3d;
font-size: 20rpx;
}
.footer_group_btn {
padding-left: 30rpx;
flex: 1;
}
}

View File

@ -0,0 +1,237 @@
<template>
<view class="show_page">
<view class="show_header_card">
<view class="show_header_status">
<view>
{{ useModel?.showData?.value?.asset_house?.full_name || '' }}
</view>
<view :class="`items_status status_${useModel?.showData?.value?.status}`">
{{
RenovationAppliesStatusEnum[
useModel?.showData?.value?.status as keyof typeof RenovationAppliesStatusEnum
]?.text
}}
</view>
</view>
<view class="show_header_cell_info">
<hs-card-cell-item title="装修类型">
{{
RenovationAppliesTypeEnum[
useModel?.showData?.value?.type as keyof typeof RenovationAppliesTypeEnum
]?.text
}}
</hs-card-cell-item>
<hs-card-cell-item title="办理类型">
{{
useModel?.showData?.value
? RenovationAppliesProcessTypeEnum[
useModel?.showData?.value
?.process_type as keyof typeof RenovationAppliesProcessTypeEnum
]?.text
: '-'
}}
</hs-card-cell-item>
<hs-card-cell-item title="装修时间">
{{ useModel?.showData?.value?.construction_start_date || '-' }}
{{ useModel?.showData?.value?.construction_end_date || '-' }}
</hs-card-cell-item>
<hs-card-cell-item title="施工状态" v-if="useModel?.showData?.value?.status === 'Approved'">
<view v-if="useModel?.showData?.value?.construction_status === 'CompletedConstruction'">
已竣工
</view>
<view v-else> 正常施工 </view>
</hs-card-cell-item>
<hs-card-cell-item title="装修内容">
{{
useModel?.showData?.value?.renovation_content
? RenovationAppliesRenovationContentEnum[
useModel?.showData?.value
?.renovation_content as keyof typeof RenovationAppliesRenovationContentEnum
]?.text
: '-'
}}
</hs-card-cell-item>
<hs-card-cell-item title="业主信息">
{{ useModel?.showData?.value?.owner_name || '-' }}
{{ useModel?.showData?.value?.owner_phone || '' }}
</hs-card-cell-item>
<hs-card-cell-item title="施工负责人">
{{ useModel?.showData?.value?.construction_principal_name || '-' }}
{{ useModel?.showData?.value?.construction_principal_phone || '' }}
</hs-card-cell-item>
<hs-card-cell-item title="装修公司名称">
{{ useModel?.showData?.value?.company_name || '-' }}
</hs-card-cell-item>
<hs-card-cell-item title="保证金金额" v-if="useModel?.showData?.value?.deposit_amount">
¥{{ useModel?.showData?.value?.deposit_amount || '-' }}
</hs-card-cell-item>
</view>
</view>
<view class="worker_contents">
<view class="worker_contents_title">
<view class="title"> 工人管理 </view>
<view class="add_worker_btn" @click="useModel.showPopupAddWorker.value = true">
<uni-icons type="plusempty" color="#2a7efb" size="14"></uni-icons> 新增工人
</view>
</view>
<cc-scroll-loading :meta="useModel?.metaData?.value" @load="method?.loadMore">
<view
v-for="(i, index) in useModel?.listData?.value"
:key="`item_${index}`"
class="worker_items"
>
<view class="worker_header">
<view class="avatar">
<image
mode="aspectFill"
:src="
(i?.worker_photo && i?.worker_photo[0]?.url) ||
' https://gc-test-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KA2RZ213C3SWAHTKT9SY7923.png'
"
/>
</view>
<view class="worker_info">
<view class="name"> {{ i.worker_name || '-' }} </view>
<view class="phone"> {{ i.worker_phone || '-' }} </view>
</view>
<view :class="`status status_${i?.visitor_apply?.status}`">
{{
VisitorAppliesStatusEnum[
i?.visitor_apply?.status as keyof typeof VisitorAppliesStatusEnum
]?.text || '-'
}}
</view>
</view>
<view class="worker_date"> 有效期{{ i?.valid_from }}{{ i?.valid_to }} </view>
<view class="worker_footer">
<view
class="btn btn_stop"
v-if="i?.visitor_apply?.status === 'Approved'"
@click="method.handleStopVisitor(i, 0)"
>
停用通行证
</view>
<view
class="btn btn_enable"
v-if="i?.visitor_apply?.status === 'Expired'"
@click="method.handleStopVisitor(i, 1)"
>
启用通行证
</view>
<view class="btn" @click="method.handleOpenDelayedEntryExit(i)"> 出入证延期 </view>
</view>
</view>
</cc-scroll-loading>
</view>
<hs-footer
v-if="
useModel?.showData?.value?.status === 'Draft' ||
useModel?.showData?.value?.status === 'Rejected'
"
:btnParimaryName="useModel?.showData?.value?.status === 'Rejected' ? '重新编辑' : '继续编辑'"
@handleParmaryClick="method.handleToPage({ url: '/ME/decoration/update/index' })"
/>
<hs-footer
v-if="
useModel?.showData?.value?.status === 'Approved' &&
!useModel?.showData?.value?.house_work_orders?.length
"
btnOtherShow
btnParimaryName="申请验收"
btnOtherName="装修延期"
@handleOtherClick="method.handleExtension"
@handleParmaryClick="method.handleAcceptance"
/>
<hs-footer
v-if="
useModel?.showData?.value?.status === 'Approved' &&
useModel?.showData?.value?.house_work_orders?.length
"
btnParimaryName="装修延期"
@handleParmaryClick="method.handleExtension"
/>
<MyPopupSelectWorker
:items="useModel.showData.value"
:show="useModel?.showPopupAddWorker?.value"
@handleClose="handleClose"
/>
<MyPopupAcceptance
:items="useModel.showData.value"
:show="useModel?.showPopupAcceptance?.value"
@handleClose="handleClose"
@handleSubmit="method.handleAcceptanceSubmit"
/>
<MyPopupExtension
:items="useModel.showData.value"
:show="useModel?.showPopupExtension?.value"
@handleClose="handleClose"
@handleSubmit="method.handleExtensionSubmit"
/>
<MyPopupDelayedEntryExit
:items="useModel.dataPopupDelayedEntryExit.value"
:show="useModel?.showPopupDelayedEntryExit?.value"
@handleClose="handleClose"
@handleSubmit="method.handleDelayedEntryExitSubmit"
/>
</view>
</template>
<script setup lang="ts">
import MyPopupAcceptance from '../components/PopupAcceptance.vue'
import MyPopupExtension from '../components/PopupExtension.vue'
import MyPopupDelayedEntryExit from '../components/PopupDelayedEntryExit.vue'
import { onHide, onLoad, onShareAppMessage, onShow, onUnload } from '@dcloudio/uni-app'
const showPopup = ref(false)
import method from './method'
import useModel from './model'
import {
RenovationAppliesStatusEnum,
RenovationAppliesProcessTypeEnum,
RenovationAppliesTypeEnum,
RenovationAppliesRenovationContentEnum,
VisitorAppliesStatusEnum,
VisitorCodeStatusEnum
} from '@/gen/Enums'
import { ref } from 'vue'
import MyPopupSelectWorker from '../components/PopupSelectWorker.vue'
onLoad((e: any) => {
method?.getShow(e)
})
onShow(() => {
if (useModel.showData.value?.id) {
method?.getShow({ id: useModel.showData.value?.id })
}
})
onHide(() => {
handleClose()
})
onUnload(() => {
useModel.showData.value = {}
useModel.listData.value = []
useModel.formListData.value = { page: 1, renovation_applies_id: '' }
})
const handleClose = () => {
useModel.showPopupAddWorker.value = false
useModel.showPopupExtension.value = false
useModel.showPopupAcceptance.value = false
useModel.showPopupDelayedEntryExit.value = false
}
onShareAppMessage(() => {
return {
title: `邀请您填写工人信息登记`,
path: `/ME/decoration/add_worker/index?id=${useModel?.showData?.value?.id}&type=share`,
imageUrl:
'https://gc-test-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KAAG9TW1WMQ8JETENG7QWXD4.jpg'
}
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,104 @@
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import userLoginStatus from '@/common/libraries/userUserLogin'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
import { useWeAppAuthStore, useWorkStore } from '@/common'
import useModel from './model'
const work = useWorkStore()
const auth = useWeAppAuthStore()
const getList = () => {
getApiLoading(Apis.Renovation.RenovationWorkers.List, useModel?.formListData?.value).then(res => {
useModel.listData.value = [...useModel.listData.value, ...res.data]
useModel.metaData.value = res.meta
console.log(res)
})
}
const getShow = (res: { id: number }) => {
getApiLoading(Apis.Renovation.RenovationApplies.Show, { id: res?.id }).then(res => {
useModel.showData.value = res?.data
useModel.formListData.value.renovation_applies_id = res?.data?.id
handleLoadList()
console.log(res)
})
}
const handleLoadList = () => {
useModel.formListData.value.page = 1
useModel.listData.value = []
getList()
}
export default {
loadMore(page: number) {
useModel.formListData.value.page = page
getList()
},
getShow,
handleToPage(i: { url?: string }) {
uni.navigateTo({
url: `${i?.url || ''}?id=${useModel?.showData?.value?.id}`
})
},
handleAcceptanceSubmit(data?: any) {
//申请验收
getApiLoading(Apis.Renovation.RenovationApplies.ApplyAccept, data).then(res => {
useModel.showPopupAcceptance.value = false
getShow(useModel?.showData?.value)
console.log(res)
})
},
handleExtensionSubmit(data?: any) {
//延期
getApiLoading(Apis.Renovation.RenovationApplies.ApplyExtension, data).then(res => {
useModel.showPopupExtension.value = false
getShow(useModel?.showData?.value)
console.log(res)
})
},
handleAcceptance(res: any) {
useModel.showPopupAcceptance.value = true
},
handleExtension(res: any) {
useModel.showPopupExtension.value = true
console.log(res)
},
handleStopVisitor(data: { id: string }, type: number) {
uni.showModal({
title: '提示',
content: type ? '确定启用通行证?' : '确定要停用通行证?',
success: function (res) {
if (res.confirm) {
if (type) {
getApiLoading(Apis.Renovation.RenovationWorkers.EnableVisitor, data).then(res => {
handleLoadList()
console.log(res)
})
} else {
getApiLoading(Apis.Renovation.RenovationWorkers.StopVisitor, data).then(res => {
handleLoadList()
console.log(res)
})
}
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
handleOpenDelayedEntryExit(i: any) {
useModel.showPopupDelayedEntryExit.value = true
useModel.dataPopupDelayedEntryExit.value = i
},
handleDelayedEntryExitSubmit(data: any) {
getApiLoading(Apis.Renovation.RenovationWorkers.UpdateVisitorTime, data).then(res => {
showToast('提交成功!', () => {
useModel.showPopupDelayedEntryExit.value = false
handleLoadList()
})
console.log(res)
})
}
}

View File

@ -0,0 +1,14 @@
import { reactive, ref } from 'vue'
export default {
listData: ref<any>([]),
formData: ref<any>({}),
metaData: ref({}),
current: ref(1),
showData: ref<any>({}),
formListData: ref({ page: 1, renovation_applies_id: '' }),
showPopupExtension: ref(false),
showPopupAcceptance: ref(false),
showPopupAddWorker: ref(false),
showPopupDelayedEntryExit: ref(false),
dataPopupDelayedEntryExit: ref<any>({})
}

View File

@ -0,0 +1,149 @@
page {
background-color: #f8f8f8;
}
.show_page {
padding-bottom: calc(130rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}
.show_header_card {
padding: 0 30rpx;
background-color: #fff;
.show_header_status {
display: flex;
align-items: center;
border-bottom: 1rpx solid #eee;
padding: 30rpx 0;
justify-content: space-between;
color: #3d3d3d;
font-size: 32rpx;
font-weight: 500;
}
.show_header_cell_info {
padding-top: 30rpx;
}
}
.items_status {
padding: 7rpx 17rpx;
border-radius: 100rpx;
font-size: 24rpx;
background-color: #f3f3f4;
color: #909399;
}
.delete_btn {
color: #666666;
font-size: 28rpx;
}
.status_Draft {
background-color: #edf4ff;
color: #0082fa;
}
.status_Pending {
background-color: #fff7ed;
color: #f97316;
}
.status_Approved {
background-color: #f0fdf4;
color: #22c55e;
}
.worker_contents {
background-color: #fff;
margin-top: 30rpx;
padding: 30rpx 0 0 0;
}
.worker_contents_title {
border-left: 6rpx solid #2a7efb;
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 30rpx;
.title {
padding-left: 10rpx;
}
.add_worker_btn {
font-size: 28rpx;
color: #2a7efb;
display: flex;
align-items: center;
}
}
.worker_items {
margin: 30rpx 30rpx 0 30rpx;
border: 1rpx solid #e5e5e5;
border-radius: 20rpx;
padding: 0 30rpx;
.worker_header {
display: flex;
align-items: center;
padding: 30rpx 0;
.avatar {
width: 100rpx;
height: 100rpx;
background-color: #f8f8f8;
border-radius: 100rpx;
image {
width: 100%;
height: 100%;
border-radius: 100rpx;
}
}
.worker_info {
flex: 1;
padding: 0 20rpx;
color: #3d3d3d;
font-size: 28rpx;
.phone {
padding-top: 5rpx;
}
}
.status {
font-size: 24rpx;
font-weight: 500;
padding: 7rpx 17rpx;
border-radius: 100rpx;
background-color: #f3f3f4;
color: #909399;
}
.status_Approved {
background-color: #f0fdf4;
color: #22c55e;
}
.status_Pending {
background-color: #fff7ed;
color: #f97316;
}
}
.worker_date {
font-size: 28rpx;
color: #666666;
}
.worker_footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 25rpx 0;
text-align: center;
font-size: 27rpx;
border-top: 1rpx solid #eee;
margin-top: 30rpx;
.btn {
flex: 1;
color: #2a7efb;
&:first-child {
height: 30rpx;
line-height: 30rpx;
border-right: 1rpx solid #eee;
}
&:last-child {
border-right: none;
}
}
.btn_stop {
color: #cf1322;
}
}
}

View File

@ -0,0 +1,320 @@
<template>
<view>
<view class="update_header">
<hs-steps :current="useModel?.current?.value" :items="['装修人信息', '施工方信息']" />
<up-steps :list="[{ name: '装修人信息' }, { name: '施工方信息' }]" :current="0"></up-steps>
</view>
<view class="update_form_content">
<template v-if="useModel?.current?.value === 0">
<view class="form_card form_card_owner">
<view class="form_card_title"> <text></text> 产权人信息 </view>
<hs-cell title="姓名" required borderTop>
<hs-input v-model:valueModel="useModel.formData.value.owner_name" textAlign="right" />
</hs-cell>
<hs-cell title="手机号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.owner_phone"
maxLength="11"
textAlign="right"
type="number"
/>
</hs-cell>
</view>
<view class="form_card">
<hs-radio-cell-picker
title="证件类型"
required
isLink
:Enums="HouseOccupantsCardTypeEnum"
v-model:valueModel="useModel.formData.value.card_type"
/>
<hs-cell title="证件号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.owner_id_card"
maxLength="18"
textAlign="right"
/>
</hs-cell>
<hs-upload-id-card
required
borderTop
v-model:valueFrontModel="useModel.formData.value.id_card_front"
v-model:valueBackModel="useModel.formData.value.id_card_back"
/>
<hs-upload
title="上传房产证"
:count="10"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.property_certificate"
/>
</view>
<!-- <view class="form_card">
<hs-cell title="是否有保证金" required>
<u-switch v-model="useModel.formData.value.is_deposit" activeColor="#2A7EFB"></u-switch>
</hs-cell>
<hs-cell title="保证金金额" v-if="useModel.formData.value.is_deposit" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.deposit_amount"
textAlign="right"
/>
</hs-cell>
</view> -->
<view class="form_card" v-if="useModel?.showData?.value?.process_type === 'AgentProcess'">
<view class="form_card_title"> <text></text> 代理人信息 </view>
<hs-cell title="姓名" required borderTop>
<hs-input v-model:valueModel="useModel.formData.value.agent_name" textAlign="right" />
</hs-cell>
<hs-cell title="手机号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.agent_phone"
maxLength="11"
textAlign="right"
type="number"
/>
</hs-cell>
<hs-radio-cell-picker
title="证件类型"
required
borderTop
isLink
:Enums="HouseOccupantsCardTypeEnum"
v-model:valueModel="useModel.formData.value.agent_card_type"
/>
<hs-cell title="证件号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.agent_id_card"
maxLength="18"
textAlign="right"
/>
</hs-cell>
<hs-upload-id-card
required
borderTop
v-model:valueFrontModel="useModel.formData.value.agent_id_card_front"
v-model:valueBackModel="useModel.formData.value.agent_id_card_back"
/>
<hs-upload
title="代理人授权书"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.power_attorney"
/>
</view>
</template>
<template v-if="useModel?.current?.value === 1">
<view class="share_card">
<view> 为保证信息正确您可分享至施工方填写 </view>
<view class="share_btn">
<button open-type="share">
分享转发 <uni-icons type="right" size="14" color="#fff"></uni-icons>
</button>
</view>
</view>
<view class="form_card">
<view class="form_card_title"> <text></text> 施工方负责人信息 </view>
<hs-cell title="姓名" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.construction_principal_name"
textAlign="right"
/>
</hs-cell>
<hs-cell title="手机号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.construction_principal_phone"
maxLength="11"
textAlign="right"
/>
</hs-cell>
<hs-radio-cell-picker
title="证件类型"
required
borderTop
isLink
:Enums="HouseOccupantsCardTypeEnum"
v-model:valueModel="useModel.formData.value.construction_principal_card_type"
/>
<hs-cell title="证件号" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.construction_principal_id_card"
maxLength="18"
textAlign="right"
/>
</hs-cell>
<hs-upload-id-card
required
borderTop
v-model:valueFrontModel="useModel.formData.value.construction_principal_id_card_front"
v-model:valueBackModel="useModel.formData.value.construction_principal_id_card_back"
/>
</view>
<view class="form_card" v-if="useModel?.formData?.value?.type === 'RenovationCompany'">
<view class="form_card_title"> <text></text> 施工公司信息 </view>
<!-- <hs-cell title="装修公司法人名称" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.company_principal_name"
textAlign="right"
/>
</hs-cell>
<hs-cell title="装修公司法人手机" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.company_principal_phone"
maxLength="11"
textAlign="right"
type="number"
/>
</hs-cell> -->
<hs-cell title="装修公司全称" required borderTop>
<hs-input v-model:valueModel="useModel.formData.value.company_name" textAlign="right" />
</hs-cell>
<hs-cell title="社会统一信用代码" required borderTop>
<hs-input
v-model:valueModel="useModel.formData.value.company_business_license_num"
textAlign="right"
/>
</hs-cell>
<hs-upload
title="营业执照照片"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.company_business_license"
/>
<hs-upload
title="资质证明"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.company_asset_certificate"
/>
<hs-upload
title="装修授权书"
:count="1"
:size="4"
required
borderTop
v-model:valueModel="useModel.formData.value.company_power_attorney"
/>
</view>
<view class="form_card">
<view class="form_card_title"> <text></text> 施工内容 </view>
<hs-date-picker
title="施工开始时间"
v-model:valueModel="useModel.formData.value.construction_start_date"
required
borderTop
isLink
/>
<hs-date-picker
title="施工结束时间"
v-model:valueModel="useModel.formData.value.construction_end_date"
required
borderTop
isLink
/>
<hs-cell title="装修内容" borderTop required>
<hs-radio
:Enums="RenovationAppliesRenovationContentEnum"
v-model:valueModel="useModel.formData.value.renovation_content"
required
/>
</hs-cell>
<view class="refund_info">
<view class="label"> 装修内容说明 </view>
<view class="refund_reason">
<textarea
v-model="useModel.formData.value.renovation_remark"
placeholder-style="color:#C9CDD4;font-size:28rpx;"
placeholder="请输入装修内容说明,例如:厨卫墙地砖拆除、安装衣柜、更换地板、客厅吊顶、全屋刷漆等"
/>
</view>
</view>
</view>
<view class="form_card">
<view class="form_card_title"> <text></text> 其他资料 </view>
<hs-upload
title="施工图"
:count="10"
:size="4"
borderTop
v-model:valueModel="useModel.formData.value.construction_draw"
/>
<hs-upload
title="装修承诺书"
:count="1"
:size="4"
borderTop
v-model:valueModel="useModel.formData.value.construction_commitment_letter"
/>
<hs-upload
title="其他附件"
:count="20"
:size="4"
borderTop
v-model:valueModel="useModel.formData.value.other_attachments"
/>
</view>
</template>
</view>
<hs-footer>
<view class="footer_page">
<view class="previous_btn" v-if="useModel?.current?.value" @click="method.handlePrev">
<uni-icons type="undo-filled" color="#3D3D3D" size="24"></uni-icons>
<view class="label"> 上一步 </view>
</view>
<view class="group_btn_content">
<view class="next_btn" @click="method.handleSave(0)">
<hs-button label="暂存" type="display" size="md" />
</view>
<view class="next_btn" @click="method.handleNextSubmit">
<hs-button
:label="useModel?.current?.value ? '提交' : '下一步'"
type="primary"
size="md"
/>
</view>
</view>
</view>
</hs-footer>
</view>
</template>
<script setup lang="ts">
import { onLoad, onShareAppMessage, onShow, onUnload } from '@dcloudio/uni-app'
import method from './method'
import useModel from './model'
import { HouseOccupantsCardTypeEnum, RenovationAppliesRenovationContentEnum } from '@/gen/Enums'
onLoad((e: any) => {
method?.getShow(e)
})
onUnload(() => {
useModel.current.value = 0
useModel.formData.value = {}
})
onShareAppMessage(() => {
return {
title: `邀请您填写装修登记`,
path: `/ME/decoration/decoration_share/index?id=${useModel?.showData?.value?.id}`,
imageUrl:
'https://gc-test-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KAAG9TW1WMQ8JETENG7QWXD4.jpg'
}
})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -0,0 +1,158 @@
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import userLoginStatus from '@/common/libraries/userUserLogin'
import { showToastBack, showToast } from '@/common/libraries/naviHelper'
import { useWeAppAuthStore, useWorkStore } from '@/common'
import useModel from './model'
const work = useWorkStore()
const auth = useWeAppAuthStore()
const handleSave = (type?: number) => {
console.log(useModel?.current?.value,type, 'useModel?.current?.value')
// 暂存
getApiLoading(Apis.Renovation.RenovationApplies.Update, {
...useModel?.formData?.value,
status: type && useModel?.current?.value ? 'Pending' : 'Draft'
}).then(res => {
if (type) {
if (useModel?.current?.value) {
showToast('提交成功!', () => {
uni.navigateBack({
delta: 1
})
})
} else {
useModel.current.value += 1
}
uni.pageScrollTo({
scrollTop: 0, // 滚动到页面的目标位置单位px
duration: 300 // 滚动动画的时长单位ms
})
} else {
showToast('暂存成功!')
}
console.log(res)
})
}
export default {
init() {
if (work?.selectWorkHouse?.asset_house) {
useModel.formData.value = {
...useModel.formData.value,
asset_houses_id: work?.selectWorkHouse?.asset_house?.id,
full_name: work?.selectWorkHouse?.asset_house?.full_name
}
} else {
useModel.formData.value = {
...useModel.formData.value,
asset_houses_id: auth?.data?.selected_house?.id,
full_name: auth?.data?.selected_house?.full_name
}
}
},
getShow(res: { id: number }) {
getApiLoading(Apis.Renovation.RenovationApplies.Show, { id: res?.id }).then(res => {
useModel.showData.value = res?.data
useModel.formData.value = {
...res?.data,
is_deposit: res?.data?.is_deposit ? true : false
}
console.log(res)
})
},
handleToSelectHouse() {
uni.navigateTo({
url: '/INDEX/asset_houses/index?type=work_add'
})
},
handleNextSubmit() {
let data = useModel?.formData?.value
if (useModel?.current?.value === 0) {
if (!data?.owner_name || !data?.owner_phone) {
return showToast('请输入产权人姓名/手机号!')
}
if (!data?.card_type) {
return showToast('请选择产权人证件类型!')
}
if (!data?.owner_id_card) {
return showToast('请输入产权人证件号!')
}
if (!data?.id_card_front?.length || !data?.id_card_back?.length) {
return showToast('请上传产权人证件!')
}
if (!data?.property_certificate?.length) {
return showToast('请上传房产证书!')
}
// if (data.is_deposit && !data?.deposit_amount) {
// return showToast('请输入保证金金额!')
// }
if (useModel?.showData?.value?.process_type === 'AgentProcess') {
if (!data?.agent_name || !data?.agent_phone) {
return showToast('请输入代理人姓名/手机号!')
}
if (!data?.agent_card_type) {
return showToast('请选择代理人证件类型!')
}
if (!data?.agent_id_card) {
return showToast('请输入代理人证件号!')
}
if (!data?.agent_id_card_front?.length || !data?.agent_id_card_back?.length) {
return showToast('请上传代理人证件!')
}
if (!data?.power_attorney?.length) {
return showToast('请上传代理人授权书!')
}
}
} else {
if (!data?.construction_principal_name) {
return showToast('请输入施工负责人名称!')
}
if (!data?.construction_principal_phone) {
return showToast('请输入施工负责人手机号!')
}
if (!data?.construction_principal_card_type) {
return showToast('请选择施工负责人证件类型!')
}
if (!data?.construction_principal_id_card) {
return showToast('请输入施工负责人证件号!')
}
if (
!data?.construction_principal_id_card_front?.length ||
!data?.construction_principal_id_card_back?.length
) {
return showToast('请上传施工负责人证件!')
}
if (useModel?.formData?.value?.type === 'RenovationCompany') {
// if (!data?.company_principal_name || !data?.company_principal_phone) {
// return showToast('请输入装修公司负责人名称/手机号!')
// }
if (!data?.company_name) {
return showToast('请设置装修公司全称!')
}
if (!data?.company_business_license_num) {
return showToast('请输入社会统一信用代码!')
}
if (!data?.company_business_license?.length) {
return showToast('请上传装修公司营业执照!')
}
if (!data?.company_asset_certificate?.length) {
return showToast('请上传装修公司资质证明!')
}
if (!data?.company_power_attorney?.length) {
return showToast('请上传装修授权书!')
}
}
if (!data?.construction_start_date || !data?.construction_end_date) {
return showToast('请选择施工时间!')
}
if (!data?.renovation_content) {
return showToast('请选择装修内容!')
}
}
handleSave(1)
},
handleSave,
handlePrev() {
useModel.current.value -= 1
}
}

View File

@ -0,0 +1,8 @@
import { reactive, ref } from 'vue'
export default {
listData: ref<any>([]),
formData: ref<any>({}),
metaData: ref({}),
current: ref(0),
showData: ref<any>({})
}

View File

@ -0,0 +1,94 @@
page {
background-color: #f8f8f8;
}
.share_card {
background: linear-gradient(180deg, #fff8f1 0%, #fff3e5 100%);
padding: 20rpx 30rpx;
color: #3d3d3d;
font-size: 26rpx;
display: flex;
align-items: center;
justify-content: space-between;
.share_btn {
display: flex;
align-items: center;
justify-content: center;
background-color: #ff8f26;
border-radius: 100rpx;
button {
padding: 0;
margin: 0;
font-size: 26rpx;
height: 55rpx;
line-height: 55rpx;
padding: 0 13rpx 0 20rpx;
background-color: transparent;
color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
}
}
}
.update_header {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #fff;
border-top: 1rpx solid #eee;
z-index: 100;
}
.update_form_content {
padding-top: 124rpx;
padding-bottom: calc(130rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}
.form_card_owner {
margin-top: 30rpx;
}
.refund_info {
border-top: 1rpx solid #eee;
background-color: #fff;
padding: 30rpx 0;
.label {
font-size: 28rpx;
}
text {
color: #f00;
}
.refund_reason {
padding: 20rpx 0 0 0;
}
}
.footer_page {
display: flex;
align-items: center;
justify-content: space-between;
.previous_btn {
padding-right: 30rpx;
.label {
font-size: 20rpx;
color: #3d3d3d;
}
}
.group_btn_content {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
.next_btn {
flex: 1;
&:first-child {
padding-right: 30rpx;
}
}
}
}
button:after {
border: none !important; /* 去掉边框 */
}

63
src/ME/surveys/index.vue Normal file
View File

@ -0,0 +1,63 @@
<template>
<view class="surveys_content">
<view class="surveys_banner">
<image
v-if="
useModel?.showData?.value?.survey?.cover_image &&
useModel?.showData?.value?.survey?.cover_image[0]?.url
"
mode="aspectFill"
:src="useModel?.showData?.value?.survey?.cover_image[0]?.url"
/>
<image
v-else
mode="widthFix"
src="https://pay-prod-1369486729.cos.ap-guangzhou.myqcloud.com/uploads/cs-test/01KPA2WCW71YA70R90YFZ6VFQQ.png"
/>
</view>
<view class="surveys_body">
<view
v-for="(i, index:number) in useModel?.showData?.value?.questions"
:key="`item_${index}`"
class="item_card"
>
<view class="title"
>{{ index + 1 }}.题目{{ i?.title }}<text v-if="i?.required">*</text></view
>
<view class="placeholder"> 提示{{ i?.placeholder }} </view>
<view class="p_t score_item_btn_group" v-if="i?.type === 'Score'">
<view
v-for="(k, idx) in useModel?.radioList"
:key="`item_${index}_${idx}`"
:class="`score_item_btn ${i?.score === k?.value ? 'score_item_btn_active' : ''}`"
@click="method?.setAnswer(index, k?.value)"
>{{ k?.label }}
</view>
</view>
<view v-else class="p_t textarea_item">
<up-textarea
placeholder="请输入回答"
style="height: 170rpx"
:maxlength="i?.max_length || 140"
count
v-model="i.answer_content"
placeholder-class="textarea_placeholder"
/>
</view>
</view>
</view>
<hs-footer @handleParmaryClick="method.handleSubmit" />
</view>
</template>
<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import method from './method'
import useModel from './model'
onLoad((e: any) => {
method?.getShow(e?.id)
console.log(e)
})
</script>
<style lang="scss">
@import './style.scss';
</style>

55
src/ME/surveys/method.ts Normal file
View File

@ -0,0 +1,55 @@
import { Apis } from '@/gen/Apis'
import { getApiLoading } from '@/common/libraries/apiLoading'
import useModel from './model'
export default {
getShow(id: string) {
getApiLoading(Apis.Survey.Surveys.Questions, { release_id: id }).then(res => {
useModel.showData.value = res?.data || {}
})
},
handleSubmit() {
let data = useModel?.showData?.value?.questions || []
let formAnswers: any = []
console.log(data, 'data')
if (data?.length) {
let isError = false
data?.map((res: any, index: number) => {
if (isError) return
if (res?.required && res?.type === 'Score' && !res?.score) {
uni.showToast({ title: `${index + 1}题请选择!`, icon: 'none' })
isError = true
return
}
if (res?.required && res?.type === 'Fill' && !res?.answer_content) {
uni.showToast({ title: `${index + 1}题请填写!`, icon: 'none' })
isError = true
return
}
formAnswers.push({
question_id: res?.id,
answer_content: res?.answer_content,
score: res?.score
})
})
if (isError) {
return
}
getApiLoading(Apis.Survey.Surveys.SubmitResponse, {
answers: formAnswers,
surveyId: useModel?.showData?.value?.survey?.id,
release_id: useModel?.showData?.value?.survey?.release_id
}).then(res => {
uni.showToast({ title: '提交成功!', icon: 'none' })
setTimeout(() => {
uni.navigateBack({ delta: 1, fail: () => {
uni.switchTab({ url: '/pages/index/index' })
} })
}, 1000)
console.log(res)
})
}
},
setAnswer(index: number, score: number) {
useModel.showData.value.questions[index].score = score
}
}

27
src/ME/surveys/model.ts Normal file
View File

@ -0,0 +1,27 @@
import { reactive, ref } from 'vue'
export default {
formData: ref<any>({}),
showData: ref<any>({}),
radioList: [
{
label: '非常不满意',
value: 1
},
{
label: '比较不满意',
value: 2
},
{
label: '满意',
value: 3
},
{
label: '比较满意',
value: 4
},
{
label: '非常满意',
value: 5
}
]
}

69
src/ME/surveys/style.scss Normal file
View File

@ -0,0 +1,69 @@
page {
background-color: #f8f8f8;
}
.surveys_content {
padding-bottom: calc(130rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
}
.surveys_banner {
height: 161px;
overflow: hidden;
image {
width: 100%;
height: 161px;
}
}
.surveys_body {
margin-top: -80rpx;
position: relative;
z-index: 100;
}
.item_card {
background-color: #fff;
margin: 30rpx;
border-radius: 15rpx;
padding: 30rpx;
.title {
color: #333333;
font-size: 30rpx;
font-weight: 500;
padding: 0 0 0 0;
text {
color: #f00;
}
}
.p_t {
padding-top: 10rpx;
}
.placeholder {
font-size: 22rpx;
color: #999;
padding: 5rpx 0 10rpx 0;
}
.score_item_btn_group {
display: flex;
align-items: center;
justify-content: space-between;
}
.score_item_btn {
border: 1px solid #d8d8d8;
border-radius: 10rpx;
padding: 12rpx 17rpx;
color: #666;
font-size: 23rpx;
}
.score_item_btn_active {
background-color: #007aff;
color: #fff;
border: 1px solid #007aff;
}
.textarea_item {
// border: 1rpx solid #eee;
// border-radius: 15rpx;
// padding: 20rpx;
}
}
.textarea_placeholder {
font-size: 26rpx;
}

View File

@ -93,4 +93,10 @@ wx-swiper .wx-swiper-dot {
.refund_reason {
padding: 20rpx 0 0 0;
}
}
.card_form {
background-color: #fff;
padding: 0 30rpx;
margin-bottom: 30rpx;
}

View File

@ -0,0 +1,3 @@
export default {
WxAppId: 'wx31500e871924b903' //小程序id
}

View File

@ -38,10 +38,15 @@ export function showToastBack(label?: string, delta = 1, back = true) {
})
}
export function showToast(label?: string) {
export function showToast(label?: string, fun?: (res: boolean) => void) {
uni.showToast({
title: label || '提交成功!',
duration: 1000,
icon: 'none'
icon: 'none',
success() {
setTimeout(() => {
return fun?.(true)
}, 1000)
}
})
}

View File

@ -3,7 +3,8 @@ import { defineStore } from 'pinia'
import { ref } from 'vue'
import { setTabBar } from '../libraries/setTabBar'
import { getApiLoading } from '../libraries/apiLoading'
const wxAppId = 'wx31500e871924b903' //小程序id
// const wxAppId = 'wx31500e871924b903' //小程序id
import config from '@/common/libraries/config'
type DataType = {
user?: {
@ -19,6 +20,12 @@ type DataType = {
house_register?: boolean
house_occupant?: boolean
is_house_exist?: number
address_city?: {
city?: string
},
current_city:{
city?: string
},
config?: {
companyAction?: {
name?: string
@ -48,7 +55,9 @@ export const useWeAppAuthStore = defineStore('we_app_auth', () => {
house_occupant: false,
house_register: false,
is_house_exist: 0,
config: {}
config: {},
address_city: {},
current_city: {}
})
function login(app: any) {
@ -62,7 +71,7 @@ export const useWeAppAuthStore = defineStore('we_app_auth', () => {
}
const getWXToken = (app: any, code: string) => {
Apis.Login.Auth.Login({ code: code, app_id: wxAppId })
Apis.Login.Auth.Login({ code: code, app_id: config?.WxAppId })
.then(res => {
console.log('登录', res?.data)
uni.setStorageSync(import.meta.env.VITE_ACCESS_TOKEN_KEY, res?.data?.token?.token)
@ -120,7 +129,7 @@ export const useWeAppAuthStore = defineStore('we_app_auth', () => {
phone_validate_code?: string
}) => {
getApiLoading(Apis.Login.Auth.BindPhoneNumber, {
app_id: wxAppId,
app_id: config?.WxAppId,
...from_data
}).then(res => {
me(() => {
@ -129,6 +138,45 @@ export const useWeAppAuthStore = defineStore('we_app_auth', () => {
})
}
const SetAddressCity = () =>{
// 高德配置
const AMAP_KEY = 'be262c006216c542747fce766130cee3'
uni.getLocation({
type: 'gcj02',
altitude: true,
isHighAccuracy: true,
success(res) {
console.log(res, '经纬度')
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${res.longitude},${res.latitude}&key=${AMAP_KEY}`
uni.request({
url: url,
method: 'GET',
success(res: any) {
console.log(res, 'address')
data.value.current_city = res?.data?.regeocode?.addressComponent
},
})
},
fail(e) {
uni.showModal({
title: '提示',
content: '请先允许定位!',
success: function (res) {
if (res.confirm) {
uni.openSetting()
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
console.log('拒绝定位', e)
}
})
}
return {
loading,
hasError,
@ -136,6 +184,7 @@ export const useWeAppAuthStore = defineStore('we_app_auth', () => {
login,
me,
handleUserLogin,
getIsHouseExist
getIsHouseExist,
SetAddressCity
}
})

View File

@ -6,11 +6,18 @@
:start="startDate"
:end="endDate"
>
<hs-cell :title="props?.title || '选择日期'" :required="props?.required" :borderTop="props?.borderTop" :value="dateValue" :isLink="props?.isLink" isPlaceholder />
</picker>
<hs-cell
:title="props?.title || '选择日期'"
:required="props?.required"
:borderTop="props?.borderTop"
:value="dateValue"
:isLink="props?.isLink"
isPlaceholder
/>
</picker>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { onMounted, ref, watch } from 'vue'
const dateValue = ref('')
// hasFutureDate:
const props = defineProps(['valueModel', 'tip','title', 'required', 'hasFutureDate','borderTop','isLink'])
@ -35,4 +42,15 @@ onMounted(() => {
: `${year - 60}-${month}-${day}`
endDate.value = `${year + 60}-${month}-${day}`
})
watch(
() => props?.valueModel,
newVal => {
console.log(newVal, 'newVal')
dateValue.value = props?.valueModel
}
)
onMounted(() => {
dateValue.value = props?.valueModel
})
</script>

View File

@ -0,0 +1,54 @@
<template>
<up-popup
:customStyle="{}"
:overlayStyle="{}"
:show="props.show"
@close="onClose"
mode="bottom"
:round="props?.round || 20"
:closeable="props?.closeable"
:bgColor="props?.bgColor || 'transparent'"
:safeAreaInsetBottom="props?.safeAreaInsetBottom || false"
>
<view class="bind_house_popup">
<view class="bind_title"> {{ props?.title || '消息通知' }} </view>
<slot></slot>
</view>
</up-popup>
</template>
<script setup lang="ts">
const props = defineProps([
'show',
'mode',
'insetBottom',
'safeAreaInsetBottom',
'round',
'closeable',
'bgColor',
'title'
])
const emit = defineEmits(['close'])
const onClose = () => {
emit('close')
}
</script>
<style lang="scss" scoped>
.bind_house_popup {
// background: linear-gradient(180deg, #d9e7ff 0%, #fdfeff 26%, #f8f8f8 47%);
background-color: #fff;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
min-height: 300rpx;
position: relative;
color: #333333;
.bind_title {
font-size: 36rpx;
font-weight: 600;
text-align: center;
padding: 23rpx 0;
}
}
</style>

View File

@ -13,14 +13,19 @@
<view class="popup_merchant_select_body">
<view class="popup_merchant_select_title"> 选择房屋 </view>
<view class="popup_search_input">
<input
placeholder="请输入关键词"
confirm-type="search"
@input="handleSearch"
@confirm="handleSearch"
placeholder-style="font-size:27rpx;color:#ccc;"
v-model="searchValue"
/>
<view class="search_city" @click="GoToCityPage">
<view class="city_name">{{ address_city }}</view> <u-icon name="arrow-down-fill" size="8" />
</view>
<view class="search_input">
<input
placeholder="请输入关键词"
confirm-type="search"
@input="handleSearch"
@confirm="handleSearch"
placeholder-style="font-size:27rpx;color:#ccc;"
v-model="searchValue"
/>
</view>
</view>
<view class="popup_tabs" v-if="popupShow">
<up-tabs :list="itemsList" :lineColor="getStyleColorValueInfo()" :current="currentValue || 0" @click="handleSwitchClick" />
@ -100,12 +105,17 @@
</view>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { getApiLoading } from '@/common/libraries/apiLoading'
import { Apis } from '@/gen/Apis'
import { debounce } from '@/common/libraries/tools'
let keywordStore = ''
import { getStyleColorValueInfo } from '@/common/libraries/getPageConfig'
import config from '@/common/libraries/config'
import { useWeAppAuthStore } from '@/common'
import { onShow, onUnload } from '@dcloudio/uni-app'
const auth = useWeAppAuthStore()
const formData = ref({ page: 1 })
const props = defineProps(['title', 'defaultValueName'])
const emit = defineEmits(['close', 'change'])
@ -121,6 +131,7 @@ const popupShow = ref(false)
const currentValue = ref(0)
const itemsList = ref([{ name: '小区' }])
const selectValueEd = ref<any>([])
const address_city = ref('深圳')
watch(
() => props?.defaultValueName,
@ -129,6 +140,16 @@ watch(
}
)
const GoToCityPage = () =>{
uni.navigateTo({
url: '/INDEX/address_city/index',
// success () {
// popupShow.value = !popupShow.value
// }
})
}
const handleSearch = debounce((e: any) => {
if (e === keywordStore) {
//
@ -140,14 +161,25 @@ const handleSearch = debounce((e: any) => {
handleTransfer(currentValue.value)
}, 500)
onShow(()=>{
address_city.value = auth?.data?.address_city?.city || auth?.data?.current_city?.city || '深圳'
currentValue.value = 0
pickerListProject.value = []
getPickerList()
})
onUnload(()=>{
auth.data.address_city= {city:''}
})
const onPopupShow = () => {
popupShow.value = !popupShow.value
if (popupShow.value) {
setTimeout(() => {
currentValue.value = 0
pickerListProject.value = []
getPickerList()
}, 300)
// setTimeout(() => {
// currentValue.value = 0
// pickerListProject.value = []
// getPickerList()
// }, 300)
}
}
@ -160,6 +192,7 @@ const handleSwitchClick = (e: any) => {
watch(
() => currentValue.value,
e => {
handleTransfer(e)
}
)
@ -182,6 +215,8 @@ const handleTransfer = (idx: number) => {
const getPickerList = () => {
getApiLoading(Apis.Asset.AssetHouses.SelectProject, {
name: searchValue.value,
app_id: config?.WxAppId,
city: address_city.value,
...formData.value
}).then(res => {
pickerListProject.value = res?.data
@ -302,8 +337,18 @@ const onSelectHouse = (i: { name: string; id: number }) => {
padding: 15rpx 20rpx;
margin: 20rpx 30rpx 0 30rpx;
border-radius: 100rpx;
border: 1rpx solid #eee;
}
.popup_tabs {
background-color: #f8f8f8;
display: flex;
align-items: center;
.search_city{
font-size: 27rpx;
color: #333;
padding-right:20rpx;
display: flex;
align-items: center;
.city_name{
margin-right: 5rpx;
}
}
}
</style>

View File

@ -58,6 +58,10 @@ const onChange = (e: any) => {
}
const getEnums = (): any => {
console.log(props?.Enums, props?.valueModel, 'valueModel')
if (props?.valueModel) {
valueEd.value = props?.Enums[props?.valueModel]?.text || ''
}
let list: EnumItem[] = Object.entries(props?.Enums as Record<string, EnumItem>).map(
([key, value]) => ({
text: value.text,
@ -73,6 +77,15 @@ watch(
getEnums()
}
)
watch(
() => props?.valueModel,
() => {
if (props?.valueModel) {
valueEd.value = props?.Enums[props?.valueModel]?.text || ''
}
}
)
onMounted(() => {
getEnums()
})
@ -96,6 +109,7 @@ onMounted(() => {
}
.placeholderStyle {
color: #ccc;
font-size: 26rpx;
}
}
</style>

View File

@ -47,6 +47,7 @@
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import { getTheFutureDay, getCurrentHour, generateTimeSlots } from '@/common/libraries/day'
import { onShow } from '@dcloudio/uni-app'
const borderStyle = '1rpx solid #eee'
const placeholder = '请选择'
interface EnumItem {
@ -63,7 +64,8 @@ const props = defineProps([
'valueExpectStartTime',
'valueExpectEndTime',
'icon',
'iconSize'
'iconSize',
'valueDefault'
])
const listData = ref<any>([])
const selectValue = ref('')
@ -85,6 +87,14 @@ const onChange = (e: any) => {
})
}
watch(
() => props?.valueDefault,
newVal => {
selectValue.value = ''
console.log('打开props.value', newVal)
}
)
const setDayList = () => {
let dayInfo = getCurrentHour()
let day0 = getTheFutureDay(0)
@ -119,6 +129,7 @@ const onColumnchange = (e: any) => {
}
onMounted(() => {
selectValue.value = ''
setDayList()
})
</script>

View File

@ -0,0 +1,187 @@
<template>
<view class="StepsContent">
<template v-for="(i, index) in props?.items" :key="index">
<view
v-if="index === 0"
:class="
props?.current > 0
? 'StepsItems StepsItemsRightActive'
: 'StepsItems StepsItemsRightDefault'
"
>
<view class="StepsDotContent">
<view class="StepsDot" :style="index <= props?.current?getStyleBgInfo():{}">
{{ index + 1 }}
</view>
<view class="label" :style="index <= props?.current?getStyleColorInfo():{}"> {{ i }} </view>
</view>
<view class="StepsItemsDivider DividerRight" :style="props?.current > 0?{backgroundColor:getStyleColorValueInfo()}:{}"> </view>
</view>
<view
v-else
:class="
index < props?.current
? 'StepsItems StepsItemsAllActive'
: index === props?.current
? 'StepsItems StepsItemsLeftActive'
: 'StepsItems'
"
>
<view class="StepsItemsDivider DividerLeft" :style="index === props?.current?{backgroundColor:getStyleColorValueInfo()}:{}"></view>
<view class="StepsDotContent">
<view class="StepsDot" :style="index <= props?.current?getStyleBgInfo():{}">
{{ index + 1 }}
</view>
<view class="label" :style="index <= props?.current?getStyleColorInfo():{}"> {{ i }} </view>
</view>
<view v-if="index < props?.items?.length - 1" class="StepsItemsDivider DividerRight"></view>
</view>
</template>
</view>
</template>
<script lang="ts" setup>
import { getStyleBgInfo ,getStyleColorInfo,getStyleColorValueInfo} from '@/common/libraries/getPageConfig'
const OnlineItems = ['创建', '生成', '签署', '交房', '完成']
const OfflineItems = ['创建', '生成', '交房', '完成']
const props = defineProps({
current: {
type: Number,
default: 0
},
items: {
type: Array,
default: ['创建', '生成', '签署', '交房', '完成']
},
data: {
type: Object,
default: {}
}
})
</script>
<style lang="scss" scoped>
.StepsContent {
width: 100%;
position: relative;
padding: 30rpx 0;
border-radius: 10rpx;
display: flex;
align-items: center;
font-weight: 400;
font-size: 26rpx;
background-color: #fff;
.StepsDotContent {
display: flex;
align-items: center;
position: relative;
background-color: #fff;
padding: 0 10px;
z-index: 10;
}
.StepsItems {
position: relative;
color: #999;
flex: 1;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
.label {
background-color: #fff;
padding: 0 5rpx 0 20rpx;
font-size: 30rpx;
}
.StepsItemsDivider {
position: absolute;
width: 50%;
height: 1rpx;
top: 0;
margin-top: 35rpx;
background-color: #d8d8d8;
z-index: 1;
}
.DividerLeft {
left: 0;
}
.DividerRight {
right: 0;
}
.StepsDot {
width: 60rpx;
height: 60rpx;
border: 1px solid #cbcbcb;
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #cbcbcb;
color: #fff;
font-size: 30rpx;
.StepsDotSolid {
background-color: #2a7efb;
width: 22rpx;
height: 22rpx;
border-radius: 100%;
}
}
}
.StepsItemsAllActive {
color: #333;
.DividerLeft,
.DividerRight {
background-color: #2a7efb;
}
.StepsDot {
border: 1px solid #2a7efb;
background-color: #2a7efb;
}
.label {
font-weight: 500;
color: #2a7efb;
}
}
.StepsItemsLeftActive {
color: #333;
.DividerLeft {
background-color: #2a7efb;
}
.StepsDot {
border: 1px solid #2a7efb;
background-color: #2a7efb;
}
.label {
font-weight: 500;
color: #2a7efb;
}
}
.StepsItemsRightActive {
color: #333;
.DividerRight {
background-color: #2a7efb;
}
.StepsDot {
border: 1px solid #2a7efb;
background-color: #2a7efb;
}
.label {
font-weight: 500;
color: #2a7efb;
}
}
.StepsItemsRightDefault {
color: #333;
.DividerRight {
background-color: #d8d8d8;
}
.StepsDot {
border: 1px solid #2a7efb;
background-color: #2a7efb;
}
.label {
font-weight: 500;
color: #2a7efb;
}
}
}
</style>

View File

@ -73,6 +73,37 @@ const handleUpload = async (type: number) => {
}
}
watch(
() => props?.valueFrontModel?.[0]?.uid,
() => {
frontImg.value = props?.valueFrontModel?.[0] || {}
},
{
deep: true
}
)
watch(
() => props?.valueBackModel?.[0]?.uid,
() => {
backImg.value = props?.valueBackModel?.[0] || {}
},
{
deep: true
}
)
onMounted(() => {
if (props?.valueBackModel && props?.valueBackModel?.length) {
backImg.value = props?.valueBackModel?.[0] || {}
}
if (props?.valueFrontModel && props?.valueFrontModel?.length) {
frontImg.value = props?.valueFrontModel?.[0] || {}
}
})
const onPreviewMedia = (url?: string) => {
console.log(url, 'url1')
if (url) {

209
src/gen/ApiTypes.d.ts vendored
View File

@ -2,10 +2,12 @@ declare namespace ApiTypes {
namespace Activity {
namespace Activities {
type List = {
"app_id"?: string; // 小程序app_id未登录时必传
"title"?: string; // 模糊搜索:名称
"asset_projects_id"?: number; // 模糊搜索项目id,[ref:asset_projects]
};
type Show = {
"app_id"?: string; // 小程序app_id未登录时必传
"id": number; // id
};
}
@ -48,6 +50,7 @@ declare namespace ApiTypes {
};
type Show = {
"id": number; // id
"asset_houses_id": number; // 房屋的id
};
type DeleteOccupant = {
"asset_houses_id": number; // 房屋的id
@ -90,10 +93,16 @@ declare namespace ApiTypes {
}
namespace Asset {
namespace AssetHouses {
type GetCities = {
"city"?: string; // -
"city_id"?: string; // -
"app_id": string; // -
};
type SelectProject = {
"name"?: string; // 项目名称
"city"?: string; // 城市名称
"city_id"?: string; // 城市id
"name"?: string; // -
"city"?: string; // -
"city_id"?: string; // -
"app_id": string; // -
};
type SelectProjectByLocation = {
"name"?: string; // -
@ -101,7 +110,8 @@ declare namespace ApiTypes {
"city_id"?: string; // -
"longitude": number; // -
"latitude": number; // -
"radius"?: number; // 搜索半径km可选
"radius"?: number; // -
"app_id": string; // -
};
type SelectBuilding = {
"asset_projects_id": number; // 所属项目ID
@ -136,6 +146,18 @@ declare namespace ApiTypes {
}
}
namespace Bill {
namespace Bills {
type List = {
"status"?: string; // 账单状态,[enum:BillsStatusEnum]
};
type Payment = {
"bill_id": number; // 账单ID
"payment_method": string; // 支付方式,[enum:HouseOrdersPaymentMethodEnum]
};
type Show = {
"bill_id": number; // 账单ID
};
}
namespace HouseBills {
type List = {
"asset_houses_id": number; // 房屋ID
@ -168,6 +190,7 @@ declare namespace ApiTypes {
namespace Common {
namespace ConvenienceServices {
type List = {
"app_id"?: string; // 小程序app_id未登录时必传
"asset_projects_id": number; // 项目ID
"type"?: string; // 模糊搜索:名称
};
@ -323,6 +346,10 @@ declare namespace ApiTypes {
};
}
}
namespace Loop {
namespace CCB {
}
}
namespace Msg {
namespace MsgPropertyAnnouncements {
type List = {
@ -332,6 +359,180 @@ declare namespace ApiTypes {
type Show = {
"id": number; // id
};
type MarkAsRead = {
"id": number; // 公告ID
};
}
}
namespace Renovation {
namespace RenovationApplies {
type List = {
"full_name"?: string; // 模糊搜索:房屋名称
"status"?: string; // 状态,[enum:RenovationAppliesStatusEnum]
"construction_status"?: string; // 施工状态,[enum:RenovationAppliesConstructionStatusEnum]
"acceptance_status"?: string; // 验收状态,[enum:RenovationAppliesAcceptanceStatusEnum]
};
type Store = {
"asset_houses_id": number; // 所属房屋id,[ref:asset_houses]
"type": string; // 装修类型,[enum:RenovationAppliesTypeEnum]
"process_type": string; // 办理类型,[enum:RenovationAppliesProcessTypeEnum]
"is_deposit"?: boolean; // 是否有保证金
"deposit_amount"?: number; // 保证金金额
"owner_name"?: string; // 业主名称
"owner_phone"?: string; // 业主手机
"card_type"?: string; // 证件类型,[enum:HouseOccupantsCardTypeEnum]
"owner_id_card"?: string; // 业主身份证
"id_card_front"?: string[]; // 身份证正面
"id_card_back"?: string[]; // 身份证反面
"property_certificate"?: string[]; // 产权证明
"agent_name"?: string; // 代理人名称
"agent_phone"?: string; // 代理人手机
"agent_card_type"?: string; // 代理人证件类型,[enum:HouseOccupantsCardTypeEnum]
"agent_id_card"?: string; // 代理人身份证
"agent_id_card_front"?: string[]; // 代理人身份证正面
"agent_id_card_back"?: string[]; // 代理人身份证反面
"power_attorney"?: string[]; // 代理人授权书
"construction_principal_name"?: string; // 施工负责人名称
"construction_principal_phone"?: string; // 施工负责人手机
"construction_principal_card_type"?: string; // 施工负责人证件类型,[enum:HouseOccupantsCardTypeEnum]
"construction_principal_id_card"?: string; // 施工负责人身份证
"construction_principal_id_card_front"?: string[]; // 施工负责人身份证正面
"construction_principal_id_card_back"?: string[]; // 施工负责人身份证反面
"construction_start_date"?: Date; // 施工开始时间
"construction_end_date"?: Date; // 施工结束时间
"renovation_content"?: string; // 装修内容,[enum:RenovationAppliesRenovationContentEnum]
"renovation_remark"?: string; // 装修备注
"construction_draw"?: string[]; // 施工图
"construction_commitment_letter"?: string[]; // 施工承诺书
"company_name"?: string; // 装修公司名称
"company_principal_name"?: string; // 装修公司负责人名称
"company_principal_phone"?: string; // 装修公司负责人手机
"company_business_license_num"?: string; // 装修公司营业执照号
"company_business_license"?: string[]; // 装修公司营业执照
"company_asset_certificate"?: string[]; // 装修公司资产证明
"company_power_attorney"?: string[]; // 装修公司装修授权书
"other_attachments"?: string[]; // 其他附件
"major_construction"?: string[]; // 主要施工项
};
type Update = {
"id": number; // id
"type"?: string; // 装修类型,[enum:RenovationAppliesTypeEnum]
"process_type"?: string; // 办理类型,[enum:RenovationAppliesProcessTypeEnum]
"is_deposit"?: boolean; // 是否有保证金
"deposit_amount"?: number; // 保证金金额
"status"?: string; // 状态,[enum:RenovationAppliesStatusEnum]
"owner_name"?: string; // 业主名称
"owner_phone"?: string; // 业主手机
"card_type"?: string; // 证件类型,[enum:HouseOccupantsCardTypeEnum]
"owner_id_card"?: string; // 业主身份证
"id_card_front"?: string[]; // 身份证正面
"id_card_back"?: string[]; // 身份证反面
"property_certificate"?: string[]; // 产权证明
"agent_name"?: string; // 代理人名称
"agent_phone"?: string; // 代理人手机
"agent_card_type"?: string; // 代理人证件类型,[enum:HouseOccupantsCardTypeEnum]
"agent_id_card"?: string; // 代理人身份证
"agent_id_card_front"?: string[]; // 代理人身份证正面
"agent_id_card_back"?: string[]; // 代理人身份证反面
"power_attorney"?: string[]; // 代理人授权书
"construction_principal_name"?: string; // 施工负责人名称
"construction_principal_phone"?: string; // 施工负责人手机
"construction_principal_card_type"?: string; // 施工负责人证件类型,[enum:HouseOccupantsCardTypeEnum]
"construction_principal_id_card"?: string; // 施工负责人身份证
"construction_principal_id_card_front"?: string[]; // 施工负责人身份证正面
"construction_principal_id_card_back"?: string[]; // 施工负责人身份证反面
"construction_start_date"?: Date; // 施工开始时间
"construction_end_date"?: Date; // 施工结束时间
"renovation_content"?: string; // 装修内容,[enum:RenovationAppliesRenovationContentEnum]
"renovation_remark"?: string; // 装修备注
"construction_draw"?: string[]; // 施工图
"construction_commitment_letter"?: string[]; // 施工承诺书
"company_name"?: string; // 装修公司名称
"company_principal_name"?: string; // 装修公司负责人名称
"company_principal_phone"?: string; // 装修公司负责人手机
"company_business_license_num"?: string; // 装修公司营业执照号
"company_business_license"?: string[]; // 装修公司营业执照
"company_asset_certificate"?: string[]; // 装修公司资产证明
"company_power_attorney"?: string[]; // 装修公司装修授权书
"other_attachments"?: string[]; // 其他附件
"major_construction"?: string[]; // 主要施工项
};
type Show = {
"id": number; // id
};
type ApplyAccept = {
"id": number; // 装修申请id
"expect_start_time"?: Date; // 期望开始时间
"expect_end_time"?: Date; // 期望结束时间
};
type ApplyExtension = {
"id": number; // 装修申请id
"extension_date": Date; // 延期日期
};
type SoftDelete = {
"id": number; // id
};
}
namespace RenovationWorkers {
type List = {
"renovation_applies_id"?: number; // 装修申请id,[ref:renovation_applies]
"worker_name"?: string; // 模糊搜索:工人姓名
"worker_phone"?: string; // 模糊搜索:工人电话
};
type Store = {
"renovation_applies_id": number; // 装修申请id,[ref:renovation_applies]
"worker_name": string; // 工人姓名
"worker_phone": string; // 工人电话
"card_type": string; // 证件类型,[enum:HouseOccupantsCardTypeEnum]
"id_card": string; // 证件号
"card_front"?: string[]; // 证件正面
"card_back"?: string[]; // 证件反面
"valid_from"?: Date; // 证件有效期开始
"valid_to"?: Date; // 证件有效期结束
"worker_photo"?: string[]; // 工人照片
};
type BatchStore = {
"renovation_applies_id": number; // 装修申请id,[ref:renovation_applies]
"workers": string[]; // 工人列表
};
type Update = {
"id": number; // id
"worker_name": string; // 工人姓名
"worker_phone": string; // 工人电话
"card_type": string; // 证件类型,[enum:HouseOccupantsCardTypeEnum]
"id_card": string; // 证件号
"card_front"?: string[]; // 证件正面
"card_back"?: string[]; // 证件反面
"valid_from"?: Date; // 证件有效期开始
"valid_to"?: Date; // 证件有效期结束
"worker_photo"?: string[]; // 工人照片
};
type Show = {
"id": number; // id
};
type StopVisitor = {
"id": number; // 工人id
};
type EnableVisitor = {
"id": number; // 工人id
};
type UpdateVisitorTime = {
"id": number; // 工人id
"visitor_start_time": string; // 访客开始时间
"visitor_end_time": string; // 访客结束时间
};
}
}
namespace Survey {
namespace Surveys {
type Questions = {
"release_id": number; // -
};
type SubmitResponse = {
"surveyId": number; // -
"release_id"?: number; // -
"answers": string[]; // -
};
}
}
namespace Visitor {

View File

@ -81,7 +81,10 @@ export const Apis = {
},
Asset: {
AssetHouses: {
SelectProject(data?: ApiTypes.Asset.AssetHouses.SelectProject): Promise<MyResponseType> {
GetCities(data: ApiTypes.Asset.AssetHouses.GetCities): Promise<MyResponseType> {
return request('customer/asset/asset_houses/get_cities', { data });
},
SelectProject(data: ApiTypes.Asset.AssetHouses.SelectProject): Promise<MyResponseType> {
return request('customer/asset/asset_houses/select_project', { data });
},
SelectProjectByLocation(data: ApiTypes.Asset.AssetHouses.SelectProjectByLocation): Promise<MyResponseType> {
@ -114,6 +117,20 @@ export const Apis = {
},
},
Bill: {
Bills: {
List(data?: ApiTypes.Bill.Bills.List): Promise<MyResponseType> {
return request('customer/bill/bills/list', { data });
},
Payment(data: ApiTypes.Bill.Bills.Payment): Promise<MyResponseType> {
return request('customer/bill/bills/payment', { data });
},
PaymentCallback(): Promise<MyResponseType> {
return request('customer/bill/bills/payment_callback', {});
},
Show(data: ApiTypes.Bill.Bills.Show): Promise<MyResponseType> {
return request('customer/bill/bills/show', { data });
},
},
HouseBills: {
List(data: ApiTypes.Bill.HouseBills.List): Promise<MyResponseType> {
return request('customer/bill/house_bills/list', { data });
@ -271,6 +288,16 @@ export const Apis = {
},
},
},
Loop: {
CCB: {
PaymentCallback(): Promise<MyResponseType> {
return request('customer/loop/c_c_b/payment_callback', {});
},
HsbPaymentCallback(): Promise<MyResponseType> {
return request('customer/loop/c_c_b/hsb_payment_callback', {});
},
},
},
Msg: {
MsgPropertyAnnouncements: {
List(data?: ApiTypes.Msg.MsgPropertyAnnouncements.List): Promise<MyResponseType> {
@ -279,11 +306,78 @@ export const Apis = {
Show(data: ApiTypes.Msg.MsgPropertyAnnouncements.Show): Promise<MyResponseType> {
return request('customer/msg/msg_property_announcements/show', { data });
},
MarkAsRead(data: ApiTypes.Msg.MsgPropertyAnnouncements.MarkAsRead): Promise<MyResponseType> {
return request('customer/msg/msg_property_announcements/mark_as_read', { data });
},
CountMsg(): Promise<MyResponseType> {
return request('customer/msg/msg_property_announcements/count_msg', {});
},
},
},
Renovation: {
RenovationApplies: {
List(data?: ApiTypes.Renovation.RenovationApplies.List): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/list', { data });
},
Store(data: ApiTypes.Renovation.RenovationApplies.Store): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/store', { data });
},
Update(data: ApiTypes.Renovation.RenovationApplies.Update): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/update', { data });
},
Show(data: ApiTypes.Renovation.RenovationApplies.Show): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/show', { data });
},
ApplyAccept(data: ApiTypes.Renovation.RenovationApplies.ApplyAccept): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/apply_accept', { data });
},
ApplyExtension(data: ApiTypes.Renovation.RenovationApplies.ApplyExtension): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/apply_extension', { data });
},
SoftDelete(data: ApiTypes.Renovation.RenovationApplies.SoftDelete): Promise<MyResponseType> {
return request('customer/renovation/renovation_applies/soft_delete', { data });
},
},
RenovationWorkers: {
List(data?: ApiTypes.Renovation.RenovationWorkers.List): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/list', { data });
},
Store(data: ApiTypes.Renovation.RenovationWorkers.Store): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/store', { data });
},
BatchStore(data: ApiTypes.Renovation.RenovationWorkers.BatchStore): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/batch_store', { data });
},
Update(data: ApiTypes.Renovation.RenovationWorkers.Update): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/update', { data });
},
Show(data: ApiTypes.Renovation.RenovationWorkers.Show): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/show', { data });
},
StopVisitor(data: ApiTypes.Renovation.RenovationWorkers.StopVisitor): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/stop_visitor', { data });
},
EnableVisitor(data: ApiTypes.Renovation.RenovationWorkers.EnableVisitor): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/enable_visitor', { data });
},
UpdateVisitorTime(data: ApiTypes.Renovation.RenovationWorkers.UpdateVisitorTime): Promise<MyResponseType> {
return request('customer/renovation/renovation_workers/update_visitor_time', { data });
},
},
},
Survey: {
Surveys: {
List(): Promise<MyResponseType> {
return request('customer/survey/surveys/list', {});
},
Questions(data: ApiTypes.Survey.Surveys.Questions): Promise<MyResponseType> {
return request('customer/survey/surveys/questions', { data });
},
SubmitResponse(data: ApiTypes.Survey.Surveys.SubmitResponse): Promise<MyResponseType> {
return request('customer/survey/surveys/submit_response', { data });
},
},
},
Visitor: {
VisitorApplies: {
Invite(data: ApiTypes.Visitor.VisitorApplies.Invite): Promise<MyResponseType> {

View File

@ -26,6 +26,13 @@ export const ActivityEnrollsStatusEnum = {
'Cancelled': {"text":"取消","color":"#ff9800","value":"Cancelled"},
};
// API凭证状态枚举
export const ApiCredentialStatusEnum = {
'Active': {"text":"启用","color":"#28A745","value":"Active"},
'Inactive': {"text":"禁用","color":"#6C757D","value":"Inactive"},
'Expired': {"text":"已过期","color":"#DC3545","value":"Expired"},
};
// 审批实例状态枚举
export const ApprovalInstancesStatusEnum = {
'Pending': {"text":"待审批","color":"#ff9800","value":"Pending"},
@ -59,6 +66,11 @@ export const ApprovalTemplatesTypeEnum = {
'Contract': {"text":"合同","color":"#2196f3","value":"Contract"},
'Finance': {"text":"财务","color":"#4caf50","value":"Finance"},
'Refund': {"text":"退款","color":"#f44336","value":"Refund"},
'ContractTermination': {"text":"合同终止","color":"#ff9800","value":"ContractTermination"},
'ContractBorrow': {"text":"合同借用","color":"#9c27b0","value":"ContractBorrow"},
'ContractPayment': {"text":"合同支付","color":"#00bcd4","value":"ContractPayment"},
'OtherContractSeal': {"text":"其它合同用印","color":"#795548","value":"OtherContractSeal"},
'HouseBillUpdate': {"text":"物业账单修改","color":"#607d8b","value":"HouseBillUpdate"},
};
// 车位产权类型
@ -227,6 +239,37 @@ export const AssetUnitsBuildingTypeEnum = {
'Tower': {"text":"塔楼","color":"#ffc107","value":"Tower"},
};
// AttendanceRecordsCheckinTypeEnum
export const AttendanceRecordsCheckinTypeEnum = {
'CheckIn': {"text":"上班","color":"#1890ff","value":"CheckIn"},
'CheckOut': {"text":"下班","color":"#52c41a","value":"CheckOut"},
};
// AttendanceRecordsStatusEnum
export const AttendanceRecordsStatusEnum = {
'Normal': {"text":"正常","color":"#52c41a","value":"Normal"},
'Late': {"text":"迟到","color":"#faad14","value":"Late"},
'EarlyLeave': {"text":"早退","color":"#fa8c16","value":"EarlyLeave"},
'OutOfRange': {"text":"范围外","color":"#ff4d4f","value":"OutOfRange"},
'Reissue': {"text":"补卡","color":"#1890ff","value":"Reissue"},
};
// AttendanceSchedulesStatusEnum
export const AttendanceSchedulesStatusEnum = {
'Pending': {"text":"待生效","color":"#faad14","value":"Pending"},
'Active': {"text":"生效中","color":"#52c41a","value":"Active"},
'Cancelled': {"text":"已取消","color":"#ff4d4f","value":"Cancelled"},
};
// 打卡状态枚举
export const AttendanceStatusEnum = {
'Normal': {"text":"正常","color":"#52c41a","value":"Normal"},
'Late': {"text":"迟到","color":"#faad14","value":"Late"},
'Early': {"text":"早退","color":"#faad14","value":"Early"},
'OutOfRange': {"text":"范围外","color":"#ff4d4f","value":"OutOfRange"},
'MakeUp': {"text":"补卡","color":"#722ed1","value":"MakeUp"},
};
// BannerSpacesTypeEnum
export const BannerSpacesTypeEnum = {
'Popup': {"text":"弹窗","color":"#ff0000","value":"Popup"},
@ -251,7 +294,7 @@ export const BannersTypeEnum = {
// 缓存类型
export const CacheTypeEnum = {
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#1de962","value":"MobilePhoneVerificationCode"},
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#16df7a","value":"MobilePhoneVerificationCode"},
};
// CompaniesMerchantTypeEnum
@ -297,12 +340,214 @@ export const CompanyEmployeeBacklogsTypeEnum = {
'MomentTask': {"text":"朋友圈任务","color":"#FF6600","value":"MomentTask"},
};
// CompanyEmployeesTypeEnum
export const CompanyEmployeesTypeEnum = {
'Staff': {"text":"员工","color":"#1890ff","value":"Staff"},
'WeCom': {"text":"企微","color":"#2196f3","value":"WeCom"},
'External': {"text":"外部","color":"#4caf50","value":"External"},
};
// CompanyReceiptAccountsPayChannelEnum
export const CompanyReceiptAccountsPayChannelEnum = {
'WeChat': {"text":"微信","color":"#07c160","value":"WeChat"},
'Alipay': {"text":"支付宝","color":"#1677ff","value":"Alipay"},
'BankTransfer': {"text":"银行转账","color":"#6c757d","value":"BankTransfer"},
'TongLian': {"text":"通联支付","color":"#ff9f0a","value":"TongLian"},
'CCB': {"text":"建行惠市宝","color":"#003da5","value":"CCB"},
};
// 公司印章类型枚举
export const CompanySealsTypeEnum = {
'OfficialSeal': {"text":"公章","color":"#007bff","value":"OfficialSeal"},
'FinanceSeal': {"text":"财务专用章","color":"#28a745","value":"FinanceSeal"},
'ContractSeal': {"text":"合同专用章","color":"#17a2b8","value":"ContractSeal"},
'LegalRepresentativeSeal': {"text":"法定代表人章","color":"#ffc107","value":"LegalRepresentativeSeal"},
'InvoiceSeal': {"text":"发票专用章","color":"#dc3545","value":"InvoiceSeal"},
'HRSeal': {"text":"人事专用章","color":"#6f42c1","value":"HRSeal"},
};
// CompanySuppliersCertificateTypeEnum
export const CompanySuppliersCertificateTypeEnum = {
'IdCard': {"text":"身份证","color":"#1e90ff","value":"IdCard"},
'BusinessLicense': {"text":"营业执照","color":"#32cd32","value":"BusinessLicense"},
};
// CompanySuppliersCounterpartyEnum
export const CompanySuppliersCounterpartyEnum = {
'Supplier': {"text":"供应商","color":"#1e90ff","value":"Supplier"},
'InternalCompany': {"text":"内部企业","color":"#32cd32","value":"InternalCompany"},
'CustomerCompany': {"text":"客户单位","color":"#ff8c00","value":"CustomerCompany"},
'Other': {"text":"其他","color":"#808080","value":"Other"},
};
// CompanySuppliersGradeEnum
export const CompanySuppliersGradeEnum = {
'Excellent': {"text":"优秀","color":"#10b981","value":"Excellent"},
'Qualified': {"text":"合格","color":"#3b82f6","value":"Qualified"},
'ToImprove': {"text":"待整改","color":"#f59e0b","value":"ToImprove"},
'Eliminated': {"text":"淘汰","color":"#ef4444","value":"Eliminated"},
};
// CompanySuppliersSupplierTypeEnum
export const CompanySuppliersSupplierTypeEnum = {
'Individual': {"text":"个人","color":"#1e90ff","value":"Individual"},
'Enterprise': {"text":"企业","color":"#32cd32","value":"Enterprise"},
};
// 合同归档借用状态枚举
export const ContractArchiveBorrowStatusEnum = {
'Pending': {"text":"审批中","color":"#f59e0b","value":"Pending"},
'Approved': {"text":"已通过","color":"#10b981","value":"Approved"},
'Rejected': {"text":"已驳回","color":"#ef4444","value":"Rejected"},
'Borrowing': {"text":"借用中","color":"#007bff","value":"Borrowing"},
'Returned': {"text":"已归还","color":"#28a745","value":"Returned"},
'Overdue': {"text":"已逾期","color":"#dc3545","value":"Overdue"},
};
// 合同归档文件归还状态枚举
export const ContractArchiveFileReturnStatusEnum = {
'NotReturned': {"text":"未归还","color":"#6c757d","value":"NotReturned"},
'Intact': {"text":"完好","color":"#28a745","value":"Intact"},
'PartialLost': {"text":"部分遗失","color":"#ffc107","value":"PartialLost"},
'AllLost': {"text":"全部遗失","color":"#dc3545","value":"AllLost"},
'AllDamaged': {"text":"全部损毁","color":"#dc3545","value":"AllDamaged"},
'PartialDamaged': {"text":"部分损毁","color":"#fd7e14","value":"PartialDamaged"},
'NoNeedReturn': {"text":"无需归还","color":"#17a2b8","value":"NoNeedReturn"},
};
// 合同归档归还状态枚举
export const ContractArchiveReturnStatusEnum = {
'NotReturned': {"text":"未归还","color":"#6c757d","value":"NotReturned"},
'Returned': {"text":"已归还","color":"#28a745","value":"Returned"},
};
// ContractArchivesConfidentialityLevelEnum
export const ContractArchivesConfidentialityLevelEnum = {
'TopSecret': {"text":"绝密","color":"#dc3545","value":"TopSecret"},
'Confidential': {"text":"机密","color":"#fd7e14","value":"Confidential"},
'Secret': {"text":"保密","color":"#ffc107","value":"Secret"},
'Internal': {"text":"内部公开","color":"#17a2b8","value":"Internal"},
'Public': {"text":"公开","color":"#28a745","value":"Public"},
};
// ContractArchivesFileStatusEnum
export const ContractArchivesFileStatusEnum = {
'Intact': {"text":"完好","color":"#28a745","value":"Intact"},
'SlightDamage': {"text":"轻度损伤","color":"#ffc107","value":"SlightDamage"},
'ModerateDamage': {"text":"中度损伤","color":"#fd7e14","value":"ModerateDamage"},
'SevereDamage': {"text":"重度损伤","color":"#dc3545","value":"SevereDamage"},
};
// ContractArchivesFileTypeEnum
export const ContractArchivesFileTypeEnum = {
'PaperOriginal': {"text":"纸质原件","color":"#007bff","value":"PaperOriginal"},
'ElectronicOriginal': {"text":"电子原件","color":"#28a745","value":"ElectronicOriginal"},
'Copy': {"text":"复印件","color":"#ffc107","value":"Copy"},
};
// ContractArchivesPeriodTypeEnum
export const ContractArchivesPeriodTypeEnum = {
'FixedTerm': {"text":"定期","color":"#007bff","value":"FixedTerm"},
'Permanent': {"text":"永久","color":"#28a745","value":"Permanent"},
};
// ContractBillObjectsAuditStatusEnum
export const ContractBillObjectsAuditStatusEnum = {
'Pending': {"text":"审批中","color":"#f59e0b","value":"Pending"},
'Approved': {"text":"已通过","color":"#10b981","value":"Approved"},
'Rejected': {"text":"已驳回","color":"#ef4444","value":"Rejected"},
};
// ContractBillObjectsStatusEnum
export const ContractBillObjectsStatusEnum = {
'Pending': {"text":"待执行","color":"#6c757d","value":"Pending"},
'InProgress': {"text":"执行中","color":"#007bff","value":"InProgress"},
'Completed': {"text":"已完成","color":"#28a745","value":"Completed"},
'Cancelled': {"text":"已取消","color":"#dc3545","value":"Cancelled"},
};
// ContractBillPaymentsStatusEnum
export const ContractBillPaymentsStatusEnum = {
'Pending': {"text":"待审","color":"#faad14","value":"Pending"},
'Approved': {"text":"已审","color":"#52c41a","value":"Approved"},
'Rejected': {"text":"驳回","color":"#f5222d","value":"Rejected"},
};
// ContractBillsAuditStatusEnum
export const ContractBillsAuditStatusEnum = {
'NotApplied': {"text":"未申请","color":"#9ca3af","value":"NotApplied"},
'Pending': {"text":"审批中","color":"#f59e0b","value":"Pending"},
'Approved': {"text":"已通过","color":"#10b981","value":"Approved"},
'Rejected': {"text":"已驳回","color":"#ef4444","value":"Rejected"},
};
// ContractBillsCostTypeEnum
export const ContractBillsCostTypeEnum = {
'Income': {"text":"收入","color":"#52c41a","value":"Income"},
'Expense': {"text":"支出","color":"#f5222d","value":"Expense"},
};
// ContractBillsIncomeExpenseTypeEnum
export const ContractBillsIncomeExpenseTypeEnum = {
'Increase': {"text":"增加","color":"#10b981","value":"Increase"},
'Decrease': {"text":"减少","color":"#ef4444","value":"Decrease"},
'Neutral': {"text":"不变","color":"#9ca3af","value":"Neutral"},
};
// ContractOthersStatusEnum
export const ContractOthersStatusEnum = {
'Pending': {"text":"审批中","color":"#f59e0b","value":"Pending"},
'Approved': {"text":"已通过","color":"#10b981","value":"Approved"},
'Rejected': {"text":"已驳回","color":"#ef4444","value":"Rejected"},
};
// ContractPeoplesSignPartyEnum
export const ContractPeoplesSignPartyEnum = {
'PartyA': {"text":"甲方","color":"#007bff","value":"PartyA"},
'PartyB': {"text":"乙方","color":"#28a745","value":"PartyB"},
'PartyC': {"text":"丙方","color":"#ffc107","value":"PartyC"},
'PartyD': {"text":"丁方","color":"#dc3545","value":"PartyD"},
};
// ContractTemplatesIncomeExpenseTypeEnum
export const ContractTemplatesIncomeExpenseTypeEnum = {
'Income': {"text":"收入类","color":"#32cd32","value":"Income"},
'Expense': {"text":"支出类","color":"#ff4500","value":"Expense"},
'None': {"text":"无收无支","color":"#808080","value":"None"},
};
// ContractTemplatesSourceEnum
export const ContractTemplatesSourceEnum = {
'Internal': {"text":"内部","color":"#1e90ff","value":"Internal"},
'External': {"text":"外部","color":"#32cd32","value":"External"},
};
// ContractsContractNatureEnum
export const ContractsContractNatureEnum = {
'RegularContract': {"text":"常规合同","color":"#007bff","value":"RegularContract"},
'FrameworkAgreement': {"text":"框架协议","color":"#28a745","value":"FrameworkAgreement"},
'Other': {"text":"其它","color":"#28a745","value":"Other"},
};
// ContractsSettlementModeEnum
export const ContractsSettlementModeEnum = {
'LumpSumContract': {"text":"总价合同","color":"#007bff","value":"LumpSumContract"},
'OpenContract': {"text":"开口合同","color":"#28a745","value":"OpenContract"},
};
// ContractsStatusEnum
export const ContractsStatusEnum = {
'TemporaryStorage': {"text":"暂存","color":"#6c757d","value":"TemporaryStorage"},
'UnderApproval': {"text":"审核中","color":"#007bff","value":"UnderApproval"},
'Approved': {"text":"已通过","color":"#28a745","value":"Approved"},
'Rejected': {"text":"已退回","color":"#dc3545","value":"Rejected"},
'Signed': {"text":"已签约","color":"#17a2b8","value":"Signed"},
'Archived': {"text":"已归档","color":"#20c997","value":"Archived"},
'Terminating': {"text":"解除中","color":"#ffc107","value":"Terminating"},
'Terminated': {"text":"已解除","color":"#fd7e14","value":"Terminated"},
'Closed': {"text":"已终止","color":"#343a40","value":"Closed"},
'Voided': {"text":"已撤销","color":"#6610f2","value":"Voided"},
'Cancelled': {"text":"已取消","color":"#e83e8c","value":"Cancelled"},
};
// ConvenienceServicesTypeEnum
@ -381,6 +626,69 @@ export const CustomerOpinionsTypeEnum = {
'FeatureSuggestion': {"text":"新功能建议","color":"#00bfff","value":"FeatureSuggestion"},
};
// 突发事件账单收支类型
export const EmergencyEventBillsCostTypeEnum = {
'Income': {"text":"收入","color":"#4caf50","value":"Income"},
'Expense': {"text":"支出","color":"#f44336","value":"Expense"},
};
// 突发事件账单费用类型
export const EmergencyEventBillsFeeTypeEnum = {
'Compensation': {"text":"赔偿","color":"#f44336","value":"Compensation"},
'Penalty': {"text":"罚款","color":"#ff9800","value":"Penalty"},
};
// 突发事件账单支付方式
export const EmergencyEventBillsPaymentMethodEnum = {
'WeChat': {"text":"微信支付","color":"#07c160","value":"WeChat"},
'Alipay': {"text":"支付宝","color":"#1677ff","value":"Alipay"},
'BankTransfer': {"text":"银行转账","color":"#2196f3","value":"BankTransfer"},
'TongLian': {"text":"通联支付","color":"#ff9800","value":"TongLian"},
'Prepayment': {"text":"预付款","color":"#9c27b0","value":"Prepayment"},
'POS': {"text":"POS机","color":"#607d8b","value":"POS"},
'Cash': {"text":"现金","color":"#4caf50","value":"Cash"},
};
// 突发事件账单支付状态
export const EmergencyEventBillsPaymentStatusEnum = {
'Pending': {"text":"待支付","color":"#ff9800","value":"Pending"},
'ToBeConfirmed': {"text":"待确认","color":"#2196f3","value":"ToBeConfirmed"},
'Paid': {"text":"已支付","color":"#4caf50","value":"Paid"},
'Refunded': {"text":"已退款","color":"#9c27b0","value":"Refunded"},
'Cancelled': {"text":"已取消","color":"#9e9e9e","value":"Cancelled"},
'Failed': {"text":"支付失败","color":"#f44336","value":"Failed"},
};
// 突发事件审核状态
export const EmergencyEventsAuditStatusEnum = {
'Pending': {"text":"待审","color":"#ff9800","value":"Pending"},
'Approved': {"text":"通过","color":"#4caf50","value":"Approved"},
'Rejected': {"text":"驳回","color":"#f44336","value":"Rejected"},
};
// 突发事件赔偿类型
export const EmergencyEventsCompensationTypeEnum = {
'Ours': {"text":"我方","color":"#2196f3","value":"Ours"},
'Others': {"text":"他方","color":"#9c27b0","value":"Others"},
};
// 突发事件状态
export const EmergencyEventsStatusEnum = {
'PendingFollowUp': {"text":"待跟进","color":"#ff9800","value":"PendingFollowUp"},
'InProgress': {"text":"跟进中","color":"#2196f3","value":"InProgress"},
'PendingReview': {"text":"待审核","color":"#9c27b0","value":"PendingReview"},
'Closed': {"text":"已关闭","color":"#9e9e9e","value":"Closed"},
};
// 突发事件行动组成员职位
export const EmergencyTeamMembersPositionEnum = {
'Leader': {"text":"应急组长","color":"#f44336","value":"Leader"},
'Member': {"text":"现场处置员","color":"#2196f3","value":"Member"},
'Liaison': {"text":"信息联络员","color":"#ffeb3b","value":"Liaison"},
'Support': {"text":"后勤保障员","color":"#4caf50","value":"Support"},
'Reserve': {"text":"机动预备员","color":"#9c27b0","value":"Reserve"},
};
// 物品放行审核状态
export const GoodsReleasesAuditStatusEnum = {
'Pending': {"text":"待审核","color":"#faad14","value":"Pending"},
@ -411,6 +719,7 @@ export const HouseBillsBillStatusEnum = {
'PartiallyPaid': {"text":"部分收款","color":"#60a5fa","value":"PartiallyPaid"},
'Paid': {"text":"已收款","color":"#10b981","value":"Paid"},
'Overdue': {"text":"已逾期","color":"#ef4444","value":"Overdue"},
'UnderApproval': {"text":"审批中","color":"#8b5cf6","value":"UnderApproval"},
'Cancelled': {"text":"已取消","color":"#9ca3af","value":"Cancelled"},
};
@ -643,6 +952,7 @@ export const HouseOrdersPaymentMethodEnum = {
'Prepayment': {"text":"预缴支付","color":"#f59e0b","value":"Prepayment"},
'POS': {"text":"POS机","color":"#8b5cf6","value":"POS"},
'Cash': {"text":"现金","color":"#dc2626","value":"Cash"},
'CCB': {"text":"建行惠市宝","color":"#003da5","value":"CCB"},
};
// HousePrepaymentLogsTypeEnum
@ -691,6 +1001,8 @@ export const HouseRegistersTypeEnum = {
'UpdateInfo': {"text":"修改信息","color":"#722ed1","value":"UpdateInfo"},
'UpdatePhone': {"text":"修改电话","color":"#13c2c2","value":"UpdatePhone"},
'GoodsRelease': {"text":"物品放行","color":"#a0d911","value":"GoodsRelease"},
'VisitorApplies': {"text":"来访申请","color":"#a0d911","value":"VisitorApplies"},
'Transfer': {"text":"过户","color":"#1890ff","value":"Transfer"},
};
// HouseRegistersUsagePlanEnum
@ -760,6 +1072,16 @@ export const HouseWorkOrdersTypeEnum = {
'Repair': {"text":"报修","color":"#ff0000","value":"Repair"},
'Incident': {"text":"报事","color":"#00aaff","value":"Incident"},
'Complaint': {"text":"投诉","color":"#aa00ff","value":"Complaint"},
'QualityCheck': {"text":"品质检查","color":"#16a085","value":"QualityCheck"},
'RenovationInspection': {"text":"装修巡检","color":"#8e44ad","value":"RenovationInspection"},
'RenovationAcceptance': {"text":"装修验收","color":"#2980b9","value":"RenovationAcceptance"},
'SecurityInspection': {"text":"安全巡检","color":"#e67e22","value":"SecurityInspection"},
};
// 公告阅读者类型
export const MsgPropertyAnnouncementReadsReaderTypeEnum = {
'Customer': {"text":"客户","color":"#3b82f6","value":"Customer"},
'Employee': {"text":"员工","color":"#10b981","value":"Employee"},
};
// 公告接收对象
@ -782,6 +1104,47 @@ export const OrganizationsTypeEnum = {
'Department': {"text":"部门","color":"#dc3545","value":"Department"},
};
// 巡逻路线生成方式
export const PatrolRoutesGenerationMethodEnum = {
'Daily': {"text":"按天","color":"#007bff","value":"Daily"},
'Weekly': {"text":"按周","color":"#28a745","value":"Weekly"},
'Monthly': {"text":"按月","color":"#ffc107","value":"Monthly"},
};
// 巡逻任务地点状态
export const PatrolTaskLocationsStatusEnum = {
'Incomplete': {"text":"未完成","color":"#ff9800","value":"Incomplete"},
'Completed': {"text":"已完成","color":"#4caf50","value":"Completed"},
};
// 巡逻任务创建方式
export const PatrolTasksCreateTypeEnum = {
'Auto': {"text":"定时生成","color":"#2196f3","value":"Auto"},
'Manual': {"text":"手动创建","color":"#4caf50","value":"Manual"},
};
// 巡逻任务状态
export const PatrolTasksStatusEnum = {
'Unassigned': {"text":"未分配","color":"#9e9e9e","value":"Unassigned"},
'Pending': {"text":"待执行","color":"#ff9800","value":"Pending"},
'InProgress': {"text":"进行中","color":"#2196f3","value":"InProgress"},
'Completed': {"text":"已完成","color":"#4caf50","value":"Completed"},
'Canceled': {"text":"已取消","color":"#f44336","value":"Canceled"},
'Overdue': {"text":"已超期","color":"#e91e63","value":"Overdue"},
};
// PayTypeEnum
export const PayTypeEnum = {
'WeChat': {"text":"微信","color":"#07c160","value":"WeChat"},
'Alipay': {"text":"支付宝","color":"#1677ff","value":"Alipay"},
};
// 题目类型枚举
export const QuestionsTypeEnum = {
'Score': {"text":"评分题","color":"#4caf50","value":"Score"},
'Fill': {"text":"填空题","color":"#2196f3","value":"Fill"},
};
// 退款状态枚举
export const RefundsStatusEnum = {
'Pending': {"text":"待审批","color":"#ff9800","value":"Pending"},
@ -806,17 +1169,121 @@ export const RefundsTypeEnum = {
'Other': {"text":"其他退款","color":"#607d8b","value":"Other"},
};
// 装修验收状态
export const RenovationAppliesAcceptanceStatusEnum = {
'PendingAcceptance': {"text":"待验收","color":"#f1c40f","value":"PendingAcceptance"},
'Accepted': {"text":"验收合格","color":"#2ecc71","value":"Accepted"},
'Rejected': {"text":"验收不合格","color":"#e74c3c","value":"Rejected"},
'Cancelled': {"text":"已取消","color":"#95a5a6","value":"Cancelled"},
};
// 装修施工状态
export const RenovationAppliesConstructionStatusEnum = {
'PendingConstruction': {"text":"待施工","color":"#f1c40f","value":"PendingConstruction"},
'NormalConstruction': {"text":"正常施工","color":"#2ecc71","value":"NormalConstruction"},
'StoppedConstruction': {"text":"已停工","color":"#e74c3c","value":"StoppedConstruction"},
'CompletedConstruction': {"text":"已竣工","color":"#3498db","value":"CompletedConstruction"},
};
// 装修办理类型
export const RenovationAppliesProcessTypeEnum = {
'OwnerProcess': {"text":"业主办理","color":"#3498db","value":"OwnerProcess"},
'AgentProcess': {"text":"代理人办理","color":"#9b59b6","value":"AgentProcess"},
};
// 装修内容
export const RenovationAppliesRenovationContentEnum = {
'PartialRenovation': {"text":"局部装修","color":"#f39c12","value":"PartialRenovation"},
'FullHouseRenovation': {"text":"全屋装修","color":"#2ecc71","value":"FullHouseRenovation"},
'PartialRefurbishment': {"text":"部分翻新","color":"#3498db","value":"PartialRefurbishment"},
};
// 装修申请状态
export const RenovationAppliesStatusEnum = {
'Draft': {"text":"暂存","color":"#f39c12","value":"Draft"},
'Pending': {"text":"审核中","color":"#faad14","value":"Pending"},
'Approved': {"text":"已完成","color":"#52c41a","value":"Approved"},
'Rejected': {"text":"驳回","color":"#f5222d","value":"Rejected"},
'Cancelled': {"text":"作废","color":"#9b59b6","value":"Cancelled"},
};
// 装修类型
export const RenovationAppliesTypeEnum = {
'SelfRenovation': {"text":"自装","color":"#1abc9c","value":"SelfRenovation"},
'RenovationCompany': {"text":"装修公司","color":"#e67e22","value":"RenovationCompany"},
};
// ResourceOrdersPaymentStatusEnum
export const ResourceOrdersPaymentStatusEnum = {
'Unpaid': {"text":"未支付","color":"#f59e0b","value":"Unpaid"},
'Paid': {"text":"已支付","color":"#10b981","value":"Paid"},
'Refunded': {"text":"已退款","color":"#3b82f6","value":"Refunded"},
};
// ResourceOrdersStatusEnum
export const ResourceOrdersStatusEnum = {
'Locked': {"text":"已锁定","color":"#8b5cf6","value":"Locked"},
'Reserved': {"text":"已预约","color":"#3b82f6","value":"Reserved"},
'Used': {"text":"已使用","color":"#10b981","value":"Used"},
'Overed': {"text":"已结束","color":"#fca5a5","value":"Overed"},
'Refunding': {"text":"退订中","color":"#f59e0b","value":"Refunding"},
'Refunded': {"text":"已退订","color":"#ef4444","value":"Refunded"},
'Closed': {"text":"已关闭","color":"#6b7280","value":"Closed"},
};
// ResourceTypesTypeEnum
export const ResourceTypesCategoryEnum = {
'Advertising': {"text":"广告","color":"#ff9800","value":"Advertising"},
'Venue': {"text":"场地","color":"#4caf50","value":"Venue"},
};
// ResourcesChannelEnum
export const ResourcesChannelEnum = {
'Consumer': {"text":"ToC","color":"#3b82f6","value":"Consumer"},
'Business': {"text":"ToB","color":"#10b981","value":"Business"},
};
// ResourcesOpenDaysEnum
export const ResourcesOpenDaysEnum = {
'Monday': {"text":"星期一","color":"#3b82f6","value":"Monday"},
'Tuesday': {"text":"星期二","color":"#3b82f6","value":"Tuesday"},
'Wednesday': {"text":"星期三","color":"#3b82f6","value":"Wednesday"},
'Thursday': {"text":"星期四","color":"#3b82f6","value":"Thursday"},
'Friday': {"text":"星期五","color":"#3b82f6","value":"Friday"},
'Saturday': {"text":"星期六","color":"#10b981","value":"Saturday"},
'Sunday': {"text":"星期日","color":"#ef4444","value":"Sunday"},
};
// ResourcesReservationRuleEnum
export const ResourcesReservationRuleEnum = {
'ByDay': {"text":"按天","color":"#3b82f6","value":"ByDay"},
'BySession': {"text":"按场次","color":"#10b981","value":"BySession"},
};
// ResourcesReservationStatusEnum
export const ResourcesReservationStatusEnum = {
'Fully': {"text":"全部预约","color":"#4caf50","value":"Fully"},
'Partially': {"text":"部分预约","color":"#ff9800","value":"Partially"},
'Not': {"text":"无预约","color":"#f44336","value":"Not"},
};
// 性别
export const SexEnum = {
'Male': {"text":"男","color":"#0000ff","value":"Male"},
'FeMale': {"text":"女","color":"#ff0000","value":"FeMale"},
};
// 问卷发布方式枚举
export const SurveyReleasesTypeEnum = {
'Manual': {"text":"手动发布","color":"#4caf50","value":"Manual"},
'Timing': {"text":"定时发布","color":"#2196f3","value":"Timing"},
};
// SysModuleEnum
export const SysModuleEnum = {
'Admin': {"text":"管理员","color":"#cf1322","value":"Admin"},
'Customer': {"text":"客户","color":"#d4b106","value":"Customer"},
'Company': {"text":"机构","color":"#1890ff","value":"Company"},
'Employee': {"text":"员工","color":"#1890ff","value":"Employee"},
};
// SysPermissionsTypeEnum
@ -824,6 +1291,8 @@ export const SysPermissionsTypeEnum = {
'Directory': {"text":"目录","color":"#6d7e14","value":"Directory"},
'Page': {"text":"页面","color":"#4d9a13","value":"Page"},
'Button': {"text":"按钮","color":"#97224f","value":"Button"},
'QuickAction': {"text":"金刚区","color":"#2563eb","value":"QuickAction"},
'Module': {"text":"模块","color":"#0d9488","value":"Module"},
};
// 来访事由

View File

@ -54,7 +54,13 @@
"setting": {
"urlCheck": false
},
"usingComponents": true
"permission": {
"scope.userLocation": {
"desc": "获取用户位置信息"
}
},
"usingComponents": true,
"requiredPrivateInfos": ["getLocation", "chooseLocation"]
},
"mp-alipay": {
"usingComponents": true

View File

@ -110,6 +110,12 @@
"navigationBarTitleText": "意见反馈"
}
},
{
"path": "surveys/index",
"style": {
"navigationBarTitleText": "问卷调查"
}
},
{
"path": "activities_show/index",
"style": {
@ -165,6 +171,42 @@
"navigationBarTitleText": "车辆管理"
}
},
{
"path": "decoration/list/index",
"style": {
"navigationBarTitleText": "装修登记"
}
},
{
"path": "decoration/add/index",
"style": {
"navigationBarTitleText": "装修登记"
}
},
{
"path": "decoration/update/index",
"style": {
"navigationBarTitleText": "装修登记"
}
},
{
"path": "decoration/show/index",
"style": {
"navigationBarTitleText": "登记详情"
}
},
{
"path": "decoration/add_worker/index",
"style": {
"navigationBarTitleText": "添加装修工人"
}
},
{
"path": "decoration/decoration_share/index",
"style": {
"navigationBarTitleText": "装修登记"
}
},
{
"path": "vehicle_management/add/index",
"style": {
@ -248,6 +290,11 @@
"style": {
"navigationBarTitleText": "入住登记"
}
},{
"path": "address_city/index",
"style": {
"navigationBarTitleText": "选择城市"
}
},
{
"path": "binding/success",

View File

@ -5,7 +5,7 @@
<view :class="showOpeningRemarks?'hide-opening-remarks':''">
<MyHeaderPrologue @handleQuickFast="handleQuickFast" />
</view>
<view :class="`chat-messages chat-messages-chat ${showOpeningRemarks?'chat-messages-update-top':''}`">
<view class="chat-messages chat-messages-chat">
<view
v-for="(message, index) in messages"
:key="index"
@ -94,25 +94,7 @@
<text>{{ i?.label }}</text>
</view>
</view>
</view>
<view
v-if="!message.actions && message.quickQuestions && message.quickQuestions.length > 0"
class="quick-questions"
>
<view
v-for="(question, qIndex) in message.quickQuestions"
:key="qIndex"
class="question-btn"
@click="handleQuickQuestion(question)"
>
<text>{{ question }}</text>
</view>
</view>
<!-- 确认按钮 -->
<!-- 确认按钮 -->
<view v-if="message.needConfirmation" class="confirmation-buttons">
<view
class="confirmation-btn"
@ -135,6 +117,27 @@
<text></text>
</view>
</view>
</view>
<view
v-if="!message.actions && message.quickQuestions && message.quickQuestions.length > 0"
class="quick-questions"
>
<view
v-for="(question, qIndex) in message.quickQuestions"
:key="qIndex"
class="question-btn"
@click="handleQuickQuestion(question)"
>
<text>{{ question }}</text>
</view>
</view>
<view v-if="message.created_at && !message.quickQuestions" class="message-meta">
<view
v-if="message.role === 'ai'"
@ -905,14 +908,20 @@ const handleSendMessage = async () => {
const hasImages = useModel?.selectedImages?.value?.length > 0
if ((!message && !hasImages) || loading.value) return
const userPhone = auth.data?.user?.phone
const projectId = auth.data?.selected_house?.asset_projects_id
const projectName = auth.data?.selected_house?.full_name
if (!userPhone || !projectId) {
if (!userPhone) {
uni.showToast({
title: '请先登录并绑定房屋',
title: '请先登录!',
icon: 'none'
})
return
}
if (!projectId) {
uni.showToast({
title: '请绑定房屋!',
icon: 'none'
})
return
@ -1096,16 +1105,16 @@ onUnmounted(() => {
})
//
onPageScroll((e) => {
if( e.scrollTop > useModel.scrollTopNumber.value){
useModel.scrollTopNumber.value = e.scrollTop
return
}
if ( useModel.scrollTopNumber.value - e.scrollTop > 60 && !showOpeningRemarks.value) {
showOpeningRemarks.value = true
}
})
// //
// onPageScroll((e) => {
// if( e.scrollTop > useModel.scrollTopNumber.value){
// useModel.scrollTopNumber.value = e.scrollTop
// return
// }
// if ( useModel.scrollTopNumber.value - e.scrollTop > 60 && !showOpeningRemarks.value) {
// showOpeningRemarks.value = true
// }
// })
onShow(() =>{
showOpeningRemarks.value = false
@ -1116,7 +1125,7 @@ onLoad(async op => {
await getCurrentInstance()?.appContext.config.globalProperties.$onLaunched
if (getLoginStatus?.getLoginStatus()) {
userLoginStatus.value = true
quickQuestionsData.value = await method?.getQuickQuestions()
useModel.quickQuestionsData.value = await method?.getQuickQuestions()
//
getHistoryMessages(1)
if (op?.message) {

View File

@ -6,7 +6,7 @@
<MyHeaderPrologue @handleQuickFast="handleQuickFast" />
</view>
<view :class="`chat-messages ${showOpeningRemarks?'chat-messages-update-top':''}`">
<view class="chat-messages">
<view
v-for="(message, index) in messages"
:key="index"
@ -94,23 +94,8 @@
<text>{{ i?.label }}</text>
</view>
</view>
</view>
<view
v-if="!message.actions && message.quickQuestions && message.quickQuestions.length > 0"
class="quick-questions"
>
<view
v-for="(question, qIndex) in message.quickQuestions"
:key="qIndex"
class="question-btn"
@click="handleQuickQuestion(question)"
>
<text>{{ question }}</text>
</view>
</view>
<!-- 确认按钮 -->
<!-- 确认按钮 -->
<view v-if="message.needConfirmation" class="confirmation-buttons">
<view
class="confirmation-btn"
@ -133,6 +118,25 @@
<text></text>
</view>
</view>
</view>
<view
v-if="!message.actions && message.quickQuestions && message.quickQuestions.length > 0"
class="quick-questions"
>
<view
v-for="(question, qIndex) in message.quickQuestions"
:key="qIndex"
class="question-btn"
@click="handleQuickQuestion(question)"
>
<text>{{ question }}</text>
</view>
</view>
<view v-if="message.created_at && !message.quickQuestions" class="message-meta">
<view
v-if="message.role === 'ai'"
@ -328,15 +332,15 @@ const goToPageLogin = () => {
}
//
onPageScroll((e) => {
if( e.scrollTop > useModel.scrollTopNumber.value){
useModel.scrollTopNumber.value = e.scrollTop
return
}
if ( useModel.scrollTopNumber.value - e.scrollTop > 60 && !showOpeningRemarks.value) {
showOpeningRemarks.value = true
}
})
// onPageScroll((e) => {
// if( e.scrollTop > useModel.scrollTopNumber.value){
// useModel.scrollTopNumber.value = e.scrollTop
// return
// }
// if ( useModel.scrollTopNumber.value - e.scrollTop > 60 && !showOpeningRemarks.value) {
// showOpeningRemarks.value = true
// }
// })
//
@ -920,9 +924,16 @@ const handleSendMessage = async () => {
const projectId = auth.data?.selected_house?.asset_projects_id
const projectName = auth.data?.selected_house?.full_name
if (!userPhone || !projectId) {
if (!userPhone) {
uni.showToast({
title: '请先登录并绑定房屋',
title: '请先登录!',
icon: 'none'
})
return
}
if (!projectId) {
uni.showToast({
title: '请绑定房屋!',
icon: 'none'
})
return

View File

@ -3,10 +3,10 @@ export default {
selectedImages: ref<string[]>([]), // 选中的图片
quickQuestionsData: ref<any>({}),
scrollTopNumber: ref(0),
API_BASE_URL: 'http://10.39.13.78:8000', //dev环境
WS_BASE_URL: 'wss://10.39.13.78:8000' //dev环境
// API_BASE_URL: 'http://10.39.13.78:8000', //dev环境
// WS_BASE_URL: 'wss://10.39.13.78:8000' //dev环境
// API_BASE_URL: 'https://kf-api-test.linyikj.com.cn', //测试环境
// WS_BASE_URL: 'wss://kf-api-test.linyikj.com.cn' //测试环境
// API_BASE_URL: 'https://kf-api.linyikj.com.cn', //正式环境
// WS_BASE_URL: 'wss://kf-api.linyikj.com.cn' //正式环境
API_BASE_URL: 'https://kf-api.linyikj.com.cn', //正式环境
WS_BASE_URL: 'wss://kf-api.linyikj.com.cn' //正式环境
}

View File

@ -246,48 +246,6 @@
.confirmation-buttons {
margin-top: 16rpx;
display: flex;
gap: 16rpx;
justify-content: flex-start;
padding-left: 12rpx;
}
.confirmation-btn {
width: 38rpx;
border-radius: 10rpx;
padding: 16rpx 22rpx;
font-size: 24rpx;
line-height: 1.4;
text-align: center;
transition: all 0.2s ease;
background-color: #fff;
color: #000;
border: 1px solid #e5e5e5;
&:active:not(.disabled) {
transform: scale(0.98);
}
&.selected {
background-color: #1c64f2;
color: #fff;
border-color: #1c64f2;
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
text {
display: block;
font-weight: 500;
}
}
.chat-input-area {
position: fixed;
bottom: 0;
@ -616,3 +574,49 @@
margin-bottom: 0rpx;
}
}
.message-content .confirmation-buttons {
margin-top: 16rpx;
display: flex;
align-items: center;
}
.message-content .confirmation-btn {
width: 100%;
border-radius: 10rpx;
padding: 14rpx 20rpx;
font-size: 24rpx;
line-height: 1.4;
text-align: center;
transition: all 0.2s ease;
background-color: #fff;
color: #000;
border: 1px solid #e5e5e5;
margin-bottom: 0 !important;
margin-right: 30rpx;
&:active:not(.disabled) {
transform: scale(0.98);
}
&.selected {
background-color: #1c64f2;
color: #fff;
border-color: #1c64f2;
}
&.disabled {
opacity: 0.6;
cursor: not-allowed;
}
text {
display: block;
font-weight: 500;
}
&:last-child {
margin-right: 0 !important;
}
}

View File

@ -15,7 +15,7 @@
</template>
</view>
</scroll-view>
<!-- <hs-scroll-indicator :scroll_view="scroll_view" /> -->
<hs-scroll-indicator :scroll_view="scroll_view" />
</view>
</template>
<script setup lang="ts">

View File

@ -14,9 +14,9 @@
</view>
</view>
<cc-scroll-loading :meta="metaData" @load="handleLoadMore">
<MyEventList v-if="current === 0" :data="convenienceServices" />
<MyEventList v-if="eventList?.length && current === 0" :data="eventList" />
<MyConvenienceServices
v-if="current === 1"
v-if="convenienceServices?.length && current === 1 || !eventList?.length && current === 0"
:data="convenienceServices"
@change="getConvenienceServices"
/>
@ -32,16 +32,27 @@ import MyEventList from './EventList.vue'
import { useWeAppAuthStore } from '@/common'
import { getStyleBgInfo } from '@/common/libraries/getPageConfig'
import getUserLogin from '@/common/libraries/userUserLogin'
import { showToast } from '@/common/libraries/naviHelper'
const loadingStatus = ref(false)
const formData = ref({ page: 1 })
const metaData = ref({})
const auth = useWeAppAuthStore()
const tabsList = [{ label: '社区活动' }, { label: '便民服务' }]
const tabsList = ref([ { label: '便民服务' }])
const current = ref(0)
const eventList = ref<any>([])
const convenienceServices = ref<any>([])
const handleTabClick = (index: number) => {
current.value = index
convenienceServices.value = []
eventList.value = []
if(!auth?.data?.selected_house){
showToast('请先选择房屋或绑定房屋!')
return false
}
if(tabsList?.value?.length === 1){
getConvenienceServices('PropertyExclusive')
return false
}
if (current.value) {
getConvenienceServices('PropertyExclusive')
} else {
@ -53,18 +64,25 @@ const getEventList = () => {
//
getApiLoading(Apis.Activity.Activities.List, {
...formData.value,
asset_projects_id: auth?.data?.selected_house?.asset_projects_id || -1,
asset_projects_id: auth?.data?.selected_house?.asset_projects_id || null,
}).then(res => {
loadingStatus.value = true
convenienceServices.value = [...convenienceServices.value, ...res.data || []]
eventList.value = [...eventList.value, ...res.data || []]
metaData.value = res.meta
if(formData.value?.page === 1 && res?.data?.length && tabsList?.value?.length === 1){
tabsList?.value?.unshift({ label: '社区活动' })
} else {
if(tabsList?.value?.length === 1){
getConvenienceServices('PropertyExclusive')
}
}
console.log('res', res)
})
}
const getConvenienceServices = (type: string) => {
//便
getApiLoading(Apis.Common.ConvenienceServices.List, {
asset_projects_id: auth?.data?.selected_house?.asset_projects_id || -1,
asset_projects_id: auth?.data?.selected_house?.asset_projects_id || null,
type: type
}).then(res => {
loadingStatus.value = true
@ -81,8 +99,12 @@ const handleLoadMore = (page: number) => {
watch(
() => auth?.data?.selected_house,
() => {
current.value = 0
convenienceServices.value = []
eventList.value = []
if (getUserLogin?.getLoginStatus() && loadingStatus.value) {
handleTabClick(current.value)
tabsList.value = [{ label: '便民服务' }]
getEventList()
}
},
{
@ -93,7 +115,9 @@ watch(
onMounted(async () => {
await getCurrentInstance()?.appContext.config.globalProperties.$onLaunched
getEventList()
if(auth?.data?.selected_house){
getEventList()
}
})
</script>
<style lang="scss" scoped>

View File

@ -2,7 +2,7 @@ page {
background-color: #f8f8f8;
}
.me_page {
padding-bottom: 68px;
padding-bottom: 78px;
background:
linear-gradient(180deg, rgba(208, 229, 255, 0.44) 0%, rgba(255, 255, 255, 0) 450rpx),
linear-gradient(146deg, #d3d7ff 0%, rgba(255, 255, 255, 0) 300rpx),