| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- <script setup>
- import { onShow } from "@dcloudio/uni-app";
- import { nextTick, reactive, ref } from "vue";
- import dayjs from "dayjs";
- import { getRuiHenTaskList } from "@/api/ruihen";
- // 搜索关键词与分页实例
- const searchKey = ref("");
- const paging = ref(null);
- const dataList = ref([]);
- // 搜索框样式
- const placeholderStyle = ref("color:#797979;font-weight:500;font-size:16px");
- const inputStyles = reactive({
- backgroundColor: "#FFFFFF",
- color: "#797979",
- });
- // 列表查询:搜索条件统一走 searchKey
- const queryList = (pageNo, pageSize) => {
- getRuiHenTaskList({
- pageNo,
- pageSize,
- searchKey: searchKey.value,
- })
- .then((res) => {
- paging.value.complete(res.data?.list || []);
- })
- .catch(() => {
- paging.value.complete(false);
- });
- };
- // 触发 z-paging 重新加载
- const searchList = () => {
- paging.value?.reload();
- };
- // 跳转新增页
- const handleCreateTask = () => {
- uni.navigateTo({
- url: "/pages/ruihen-task/create",
- });
- };
- // 跳转详情页
- const handleView = (item) => {
- uni.navigateTo({
- url: "/pages/ruihen-task/detail?id=" + item.id,
- });
- };
- // 跳转编辑页
- const handleEdit = (item) => {
- uni.navigateTo({
- url: "/pages/ruihen-task/edit?id=" + item.id,
- });
- };
- // 同时兼容秒级和毫秒级时间戳
- const normalizeTimestamp = (time) => {
- if (!time) return null;
- const value = Number(time);
- if (Number.isNaN(value)) return time;
- return value < 1000000000000 ? value * 1000 : value;
- };
- // 创建时间格式化
- const formatTime = (time) => {
- const value = normalizeTimestamp(time);
- return value ? dayjs(value).format("YYYY-MM-DD HH:mm:ss") : "——";
- };
- // 施工队伍兼容数组和字符串两种返回结构
- const formatDeptNames = (deptNames) => {
- if (Array.isArray(deptNames)) {
- return deptNames.filter(Boolean).join("、") || "——";
- }
- return deptNames || "——";
- };
- onShow(() => {
- nextTick(() => {
- searchList();
- });
- });
- </script>
- <template>
- <z-paging class="page" ref="paging" v-model="dataList" @query="queryList">
- <template #top>
- <view class="top">
- <!-- 搜索区 -->
- <view class="search-row">
- <uni-easyinput
- v-model="searchKey"
- :styles="inputStyles"
- :placeholderStyle="placeholderStyle"
- :placeholder="$t('operation.searchText')"
- @confirm="searchList" />
- <button
- class="mini-btn"
- type="primary"
- size="mini"
- @click="searchList">
- {{ $t("operation.search") }}
- </button>
- </view>
- <!-- 查询区下方新增按钮 -->
- <button
- class="create-btn"
- style="width: 100%"
- type="primary"
- size="mini"
- @click="handleCreateTask">
- 新增任务
- </button>
- </view>
- </template>
- <view class="list">
- <!-- 任务卡片列表 -->
- <view
- class="item"
- v-for="(item, index) in dataList"
- :key="item.id || index">
- <view class="header">
- <!-- 右上角状态固定统一蓝色,仅展示 statusLabel -->
- <span class="contract-name"
- >合同名称:{{ item.contractName || "——" }}</span
- >
- <span class="status-tag">{{ item.statusLabel || "——" }}</span>
- </view>
- <view class="content">
- <view class="content-item">
- <span class="label">井号:</span>
- <span>{{ item.wellName || "——" }}</span>
- </view>
- <view class="content-item">
- <span class="label">施工地点:</span>
- <span>{{ item.location || "——" }}</span>
- </view>
- <view class="content-item">
- <span class="label">施工队伍:</span>
- <span>{{ formatDeptNames(item.deptNames) }}</span>
- </view>
- <view class="content-item">
- <span class="label">创建时间:</span>
- <span>{{ formatTime(item.createTime) }}</span>
- </view>
- </view>
- <view class="footer">
- <!-- 列表操作按钮 -->
- <button
- class="button"
- size="mini"
- type="primary"
- plain="true"
- @click="handleView(item)">
- {{ $t("operation.view") }}
- </button>
- <button
- class="button"
- size="mini"
- type="primary"
- @click="handleEdit(item)">
- {{ $t("operation.edit") }}
- </button>
- </view>
- </view>
- </view>
- </z-paging>
- </template>
- <style scoped>
- .page {
- padding: 10px;
- }
- .top {
- display: flex;
- flex-direction: column;
- gap: 12px;
- background: #f3f5f9;
- padding: 10px 0;
- }
- .search-row {
- display: flex;
- align-items: center;
- gap: 12px;
- }
- .search-row :deep(.uni-easyinput) {
- flex: 1;
- }
- :deep(.mini-btn) {
- height: 38px !important;
- font-size: 16px !important;
- margin: 0;
- }
- .create-btn {
- margin: 0;
- align-self: flex-start;
- }
- .list {
- margin-top: 16px;
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
- .item {
- background-color: #fff;
- padding: 12px;
- border-radius: 8px;
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
- .header {
- display: flex;
- align-items: flex-start;
- justify-content: space-between;
- gap: 12px;
- }
- .contract-name {
- flex: 1;
- font-size: 16px;
- font-weight: 600;
- color: #1f2329;
- word-break: break-all;
- }
- .status-tag {
- flex-shrink: 0;
- display: inline-flex;
- align-items: center;
- padding: 5px 10px;
- border-radius: 4px;
- font-size: 14px;
- font-weight: 500;
- color: #1677ff;
- background: rgba(22, 119, 255, 0.12);
- }
- .content {
- display: flex;
- flex-direction: column;
- gap: 8px;
- }
- .content-item {
- font-size: 14px;
- font-weight: 400;
- color: #4e5969;
- word-break: break-all;
- }
- .label {
- display: inline-block;
- width: 76px;
- font-weight: 500;
- color: #1f2329;
- }
- .footer {
- display: flex;
- justify-content: flex-end;
- align-items: center;
- gap: 12px;
- }
- .button {
- margin: 0;
- }
- </style>
|