You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
5.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<!-- 生成记录列表 -->
<view class="record-list">
<div v-for="record in list" :key="record.ID">
<view class="record-item">
<!-- 记录信息 -->
<view class="record-info">
<view class="record-title">{{ record.name }}</view>
<view class="record-time">
{{ record.description }}
</view>
</view>
<!-- 操作按钮 -->
<view class="record-actions">
<uv-button type="primary" size="small" v-if="record.access_status == 'rejected' || record.access_status == 'none'"
@click="openApplyModal(record)">
申请权限
</uv-button>
</view>
<!-- 状态标签 -->
<view class="status-tag" :class="{
completed: record.access_status == 'approved',
failed: record.access_status == 'rejected',
waitting: record.access_status == 'pending',
}">
{{get_access_status(record.access_status)}}
</view>
</view>
</div>
</view>
<!-- 空状态 -->
<view v-if="list.length === 0 && loadingStatus !== 'loading'" class="empty-state">
<uv-icon name="file-text" size="60" color="#ccc"></uv-icon>
<text class="empty-text">暂无模板</text>
</view>
<uv-modal
ref="applyModalRef"
showCancelButton
title="申请权限"
@confirm="confirmApply"
@cancel="cancelApply"
>
<view class="apply-modal-content">
<view class="apply-label"></view>
<uv-textarea
v-model="applyReason"
placeholder="请输入申请理由"
maxlength="200"
count
></uv-textarea>
</view>
</uv-modal>
<!-- 加载更多 -->
<!-- <uv-load-more v-else :status="loadingStatus" @loadmore="loadmore" /> -->
</view>
</template>
<script setup>
import {
ref,
onMounted
} from "vue";
import RPC from "@/utils/request";
import dayjs from "dayjs";
import {
onShow,
onPullDownRefresh,
onReachBottom
} from "@dcloudio/uni-app";
// 响应式数据
const loading = ref(false);
const loadingStatus = ref("loadmore");
const page = ref(1);
const list = ref([]);
const count = ref(0);
// 加载生成记录
const loadRecords = async () => {
uni.showLoading();
loadingStatus.value = "loading";
RPC.post("/template/list_with_access", {
page: 1,
limit: -1,
})
.then((res) => {
list.value = (res.rows || []).filter((item) => item.enabled);
})
.finally(() => {
uni.hideLoading();
});
};
// 刷新数据
onPullDownRefresh(() => {
loadRecords();
uni.stopPullDownRefresh();
});
const get_access_status = (access_status) => {
let str = "";
if (access_status === "none") {
str = "无权限";
} else if (access_status === "pending") {
str = "待审批";
} else if (access_status === "rejected") {
str = "已拒绝";
} else if (access_status === "approved") {
str = "已通过";
} else {
str = access_status;
}
return str;
};
onShow(() => {
// 页面显示时刷新数据
list.value = [];
page.value = 1;
loadRecords();
});
const currentTemplate = ref({})
// 打开申请权限弹框
const openApplyModal = (item) => {
applyReason.value = "";
currentTemplate.value = item
applyModalRef.value.open();
};
const applyLoading = ref(false)
const applyReason = ref('')
const applyModalRef = ref(null)
// 确认申请权限
const confirmApply = async () => {
if (!applyReason.value.trim()) {
uni.showToast({
title: "请输入申请理由",
icon: "error",
});
return;
}
applyLoading.value = true;
try {
await RPC.post("/template_access_apply", {
template_id: currentTemplate.value.id,
reason: applyReason.value.trim(),
});
uni.showToast({
title: "申请已提交",
icon: "success",
});
applyModalRef.value.close();
applyReason.value = "";
loadRecords();
} catch (error) {
uni.showToast({
title: "申请失败,请重试",
icon: "error",
});
} finally {
applyLoading.value = false;
}
};
// 取消申请
const cancelApply = () => {
applyReason.value = "";
};
</script>
<style lang="scss" scoped>
.container {
font-size: 14px;
min-height: 100vh;
background-color: #f8f8f8;
padding: 16px;
}
.record-list {
.record-item {
background: white;
border-radius: 12px;
padding: 16px;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 12px;
.record-info {
flex: 1;
overflow: auto;
.record-title {
width: 100%;
font-size: 16px;
color: #333;
font-weight: 500;
margin-bottom: 6px;
word-wrap: break-word;
white-space: normal;
}
.record-time {
font-size: 13px;
color: #999;
}
}
.status-tag {
flex-shrink: 0;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
background: #eee;
color: #333;
&.waitting {
background: #fff7e6;
color: #fa8c16;
}
&.completed {
background: #e8f5e8;
color: #52c41a;
}
&.failed {
background: #fff1f0;
color: #ff4d4f;
}
&.processing {
background: #fff7e6;
color: #fa8c16;
}
}
.record-actions {
display: flex;
align-items: center;
flex-shrink: 0;
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px 20px;
.empty-text {
color: #999;
font-size: 14px;
margin-top: 16px;
}
}
.load-more {
padding: 20px;
text-align: center;
}
.apply-modal-content {
padding: 20px 0;
width: 100%;
.apply-label {
font-size: 14px;
color: #333;
margin-bottom: 12px;
}
}
</style>