123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- <template>
- <hc-sys id="app-sys" class="hc-work-order-page" navBarUi='work-order-nav-bar'>
- <template #navBar>
- <hc-nav-back-bar ui='work-order-nav' title="消息动态圈">
- <text class="i-ri-add-circle-fill text-40 mr-1" @click="toPageClick('/pages/work-order/add')"/>
- <text class="i-ri-message-3-fill text-40 ml-2"/>
- </hc-nav-back-bar>
- </template>
- <!--下拉刷新区域-->
- <z-paging ref="pageRef" :style="pagingStyle" v-model="dataList" @query="getDataList">
- <uni-collapse>
- <template v-for="item in dataList" :key="item.id">
- <view class="relative bg-white mb-2 p-3">
- <view class="hc-flex">
- <view class="hc-flex-center mr-3">
- <hc-img class="round" :width="40" :height="40" :src="item.avatar" v-if="item.avatar"/>
- <hc-img class="round" :width="40" :height="40" src="/static/image/avatar.png" v-else/>
- </view>
- <view class="relative flex-1">
- <view class="text-black mb-1">{{item['createUserName'] ?? '用户名异常'}}</view>
- <view class="text-24 text-gray-4">{{item['createTime']}}</view>
- </view>
- <view class="text-24 text-gray-5" v-if="parseInt(item['isSolve']) === 1">已解决</view>
- </view>
- <view class="relative ml-12.5 text-gray-5">
- <view class="relative mt-3" v-html="item['opinionContent']"/>
- <view class="mt-3" v-if="item['returnFiles']?.length > 0">
- <hc-row :gutter="10">
- <hc-col :span="8" class="h-125" v-for="(img, index) in item['returnFiles']">
- <hc-image class="radius" un-border="1 solid gray-2" :src="img" @click="previewImage(item['returnFiles'], index)"/>
- </hc-col>
- </hc-row>
- </view>
- </view>
- <view class="hc-flex ml-12.5 mt-4 text-gray-5">
- <view class="hc-flex text-34" @click="commentExpanded(item)">
- <text class="i-ri-message-2-fill" v-if="item['commentExpanded']"/>
- <text class="i-ri-message-2-line" v-else/>
- <text class="text-26 text-gray-5 ml-1" v-if="item['commentsNumber'] >= 1">{{ item['commentsNumber'] }}</text>
- </view>
- <view class="flex-1"/>
- <view class="hc-flex text-34" @click="goodLikeClick(item)">
- <text class="i-ri-thumb-up-fill" v-if="item['currentUserGood']"/>
- <text class="i-ri-thumb-up-line" v-else/>
- <text class="text-26 text-gray-5 ml-1" v-if="item['goodNumber'] >= 1">{{ item['goodNumber'] }}</text>
- </view>
- </view>
- <!--评论区域-->
- <uni-collapse-item :class="item['commentExpanded']?'mt-3':''" title="评论区" :open="item['commentExpanded'] ?? false">
- <view class="relative pt-3" un-border-t="1 solid gray-2">
- <view class="relative flex items-end mb-5">
- <view class="relative flex-1">
- <textarea v-model="item.userCommentContent" class="hc-textarea p-2 text-26" placeholder="请输入评论内容" auto-height />
- </view>
- <button class="cu-btn text-24 ml-2" :class="item['userCommentContent']?'bg-blue-5 text-white':''" @click="submitComment(item)">提交</button>
- </view>
- <view class="relative flex items-start" v-for="(items, index) in item['expandedCommentList']" :key="items.id">
- <view class="mr-2">
- <hc-img class="round" :width="24" :height="24" :src="items.avatar" v-if="items.avatar"/>
- <hc-img class="round" :width="24" :height="24" src="/static/image/avatar.png" v-else/>
- </view>
- <view class="relative flex-1">
- <view class="flex items-start">
- <view class="flex-1 text-28 text-gray-7">{{items['userName'] ?? '用户名异常'}}</view>
- <text class="text-24 text-gray-4">{{items['createTime']}}</text>
- </view>
- <view class="text-24 text-gray-4 mt-1" v-html="items['replyContent']"/>
- <view class="relative my-3" un-border-b="1 solid gray-2" v-if="(item['expandedCommentList'].length - 1) !== index"/>
- </view>
- </view>
- </view>
- </uni-collapse-item>
- </view>
- </template>
- </uni-collapse>
- </z-paging>
- </hc-sys>
- </template>
- <script setup>
- import {getCurrentInstance, ref} from "vue";
- import mainApi from '~api/other/work-order';
- import {onShow, onReady} from '@dcloudio/uni-app'
- import {errorToast, querySelect, successToast} from "@/utils/tools";
- import {arrToKey, getArrValue, getObjValue} from "js-fast-way";
- import {useAppStore} from "@/store";
- //初始变量
- const store = useAppStore()
- const projectId = ref(store.projectId);
- const contractId = ref(store.contractId);
- const instance = getCurrentInstance().proxy
- const isNodes = ref(false)
- const pageRef = ref(null)
- onReady(() => {
- setPagingStyle()
- isNodes.value = true
- })
- onShow(() => {
- if (isNodes.value) {
- reloadData()
- }
- })
- //内容区域
- const pagingStyle = ref({
- position: 'relative',
- width: '100%',
- bottom: 0,
- })
- const setPagingStyle = async () => {
- const {height: appHeight} = await querySelect(instance, 'app-sys')
- const {height: navHeight} = await querySelect(instance, 'hc-nav-bar')
- // #ifdef H5
- pagingStyle.value.height = (appHeight - navHeight) + 'px'
- // #endif
- // #ifdef APP-PLUS
- const {screenHeight, safeArea} = uni.getWindowInfo()
- const content = navHeight + (screenHeight - safeArea.bottom)
- pagingStyle.value.height = (screenHeight - content) + 'px'
- // #endif
- }
- //重载数据
- const reloadData = () => {
- pageRef.value?.reload()
- }
- //获取数据
- const dataList = ref([])
- const getDataList = async (pageNo, pageSize) => {
- uni.showLoading({title: '获取数据中...', mask: true});
- const { data } = await mainApi.queryUserOpinionPage({
- projectId: projectId.value,
- contractId: contractId.value,
- current: pageNo,
- size: pageSize,
- })
- const res = getObjValue(data)
- isNodes.value = true
- pageRef.value?.complete(getArrValue(res?.records));
- uni.hideLoading();
- }
- //预览图片
- const previewImage = (imgs, index) => {
- uni.previewImage({
- urls: imgs,
- current: index
- });
- }
- //评论展开或收起
- const commentExpanded = (item) => {
- if (!item['commentExpanded']) {
- queryCommentsList(item)
- } else {
- item['commentExpanded'] = false
- }
- }
- //获取评论列表
- const queryCommentsList = async (item) => {
- uni.showLoading({title: '获取评论数据中...', mask: true});
- //关闭其他评论区
- for (let i = 0; i < dataList.value.length; i++) {
- const item = dataList.value[i]
- if (item['commentExpanded']) {
- item['commentExpanded'] = false
- }
- }
- //发起请求
- const {data} = await mainApi.queryCommentsList({
- userOpinionId: item.id
- })
- item['expandedCommentList'] = getArrValue(data)
- item['commentExpanded'] = true
- uni.hideLoading();
- }
- //提交评论
- const submitComment = async (item) => {
- if (!item['userCommentContent']) {
- errorToast('请先填写评论内容')
- return
- }
- //发起请求
- uni.showLoading({title: '提交数据中...', mask: true});
- const {error, code} = await mainApi.saveUserComments({
- userOpinionId: item.id,
- replyContent: item['userCommentContent'],
- projectId: projectId.value,
- contractId: contractId.value,
- })
- uni.hideLoading();
- if (!error && code === 200) {
- item['userCommentContent'] = ''
- queryCommentsList(item).then()
- } else {
- errorToast('评论失败')
- }
- }
- //点赞或取消点赞
- const goodLikeClick = async (item) => {
- if (item['currentUserGood']) {
- const {error, code} = await mainApi.cancelGood({
- userOpinionId: item.id
- })
- if (!error && code === 200) {
- item['currentUserGood'] = false
- item['goodNumber']--
- } else {
- errorToast('取消点赞失败')
- }
- } else {
- const {error, code} = await mainApi.addGoodNumber({
- userOpinionId: item.id,
- good: 1
- })
- if (!error && code === 200) {
- item['currentUserGood'] = true
- item['goodNumber']++
- } else {
- errorToast('点赞失败')
- }
- }
- }
- //跳转到其他页面
- const toPageClick = (url) => {
- uni.navigateTo({url: url});
- }
- </script>
- <style lang="scss">
- @import "@/style/work-order/index.scss";
- </style>
|