|
@@ -0,0 +1,457 @@
|
|
|
|
|
+<!-- 使用 type="home" 属性设置首页,其他页面不需要设置,默认为page;推荐使用json5,更强大,且允许注释 -->
|
|
|
|
|
+<route lang="json5">
|
|
|
|
|
+{
|
|
|
|
|
+ style: {
|
|
|
|
|
+ navigationBarTitleText: '打印任务列表',
|
|
|
|
|
+ },
|
|
|
|
|
+}
|
|
|
|
|
+</route>
|
|
|
|
|
+<template>
|
|
|
|
|
+ <view class="page-list">
|
|
|
|
|
+ <wd-sticky>
|
|
|
|
|
+ <view class="sticky-box">
|
|
|
|
|
+ <wd-tabs v-model="queryParams.completed" auto-line-width @change="resetDataList">
|
|
|
|
|
+ <wd-tab v-for="item of completedList" :key="item.value" :title="item.label" :name="item.value">
|
|
|
|
|
+ </wd-tab>
|
|
|
|
|
+ </wd-tabs>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- <wd-search
|
|
|
|
|
+ placeholder="请输入打印任务名称"
|
|
|
|
|
+ placeholder-left
|
|
|
|
|
+ hide-cancel
|
|
|
|
|
+ v-model="queryParams.title"
|
|
|
|
|
+ @change="onSearch"
|
|
|
|
|
+ @clear="onSearch"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template v-slot:prefix>
|
|
|
|
|
+ <wd-drop-menu custom-class="search-menu">
|
|
|
|
|
+ <wd-drop-menu-item v-model="queryParams.completed" :options="completedList" @change="onSearch" />
|
|
|
|
|
+ </wd-drop-menu>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </wd-search> -->
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </wd-sticky>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="list-contain">
|
|
|
|
|
+ <view v-if="queryParams.printer" class="printer">{{ `当前打印机: ${queryParams.printer}` }}</view>
|
|
|
|
|
+
|
|
|
|
|
+ <template v-if="dataList.length > 0 || loadStatus == 'loading'">
|
|
|
|
|
+ <view v-for="item of dataList" :key="item.id" class="item-contain" @click="toDetail(item.id)">
|
|
|
|
|
+ <view class="item-info">
|
|
|
|
|
+ <view class="image">
|
|
|
|
|
+ <wd-img
|
|
|
|
|
+ :src="getFileType(item.title)"
|
|
|
|
|
+ :width="60"
|
|
|
|
|
+ :height="60"
|
|
|
|
|
+ mode="aspectFit"
|
|
|
|
|
+ ></wd-img>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="name">
|
|
|
|
|
+ <view class="main-text">
|
|
|
|
|
+ <view>{{ item.title }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="sub-text">
|
|
|
|
|
+ <text>任务状态: </text>
|
|
|
|
|
+ <text :class="`color-${getLabelColor(item.jobStatus, jobStatus)}`">{{ getLabel(item.jobStatus, jobStatus) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="sub-text">
|
|
|
|
|
+ {{ `创建时间: ${item.createTime}` }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- <view class="sub-text flex-center">
|
|
|
|
|
+ <view class="flex-1">xxx</view>
|
|
|
|
|
+ <view class="flex-1">xxx</view>
|
|
|
|
|
+ </view> -->
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- <view class="opt" @click.stop="showActions(item)">
|
|
|
|
|
+ <wd-button type="icon" icon="more"></wd-button>
|
|
|
|
|
+ </view> -->
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="item-opt">
|
|
|
|
|
+ <!-- <view class="opt-btn">详情</view> -->
|
|
|
|
|
+ <view v-if="item.reprint == '1'" class="opt-btn" @click.stop="handleReprint(item.id)">重打</view>
|
|
|
|
|
+ <view v-if="['3', '4', '5', '6'].includes(item.jobStatus)" class="opt-btn" @click.stop="handleCancel(item.id)">取消</view>
|
|
|
|
|
+ <view class="opt-btn delete-btn" @click.stop="handleDelete(item)">删除</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 加载更多 -->
|
|
|
|
|
+ <wd-loadmore custom-class="loadmore" :state="loadStatus" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <wd-status-tip v-else image="content" tip="暂无内容" />
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 动作面板 -->
|
|
|
|
|
+ <wd-action-sheet
|
|
|
|
|
+ v-model="isShowActions"
|
|
|
|
|
+ :actions="currentActions"
|
|
|
|
|
+ :title="actionsTitle"
|
|
|
|
|
+ @close="isShowActions = false"
|
|
|
|
|
+ @select="selectActions"
|
|
|
|
|
+ />
|
|
|
|
|
+ </view>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+import { useMessage, useToast } from 'wot-design-uni'
|
|
|
|
|
+import { getUserHubJobsPage, reprintUserHubJobs, cancelUserHubJobs, deleteUserHubJobs } from '@/service/api'
|
|
|
|
|
+import { getLabel, getLabelColor } from '@/utils'
|
|
|
|
|
+import { debounce } from 'wot-design-uni/components/common/util'
|
|
|
|
|
+
|
|
|
|
|
+const message = useMessage()
|
|
|
|
|
+const toast = useToast()
|
|
|
|
|
+const total = ref(0)
|
|
|
|
|
+const queryParams: any = reactive({
|
|
|
|
|
+ pageNo: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ completed: "all",
|
|
|
|
|
+ title: '',
|
|
|
|
|
+ printer: "",
|
|
|
|
|
+})
|
|
|
|
|
+const completedList: any = ref([
|
|
|
|
|
+ { label: '全部', value: 'all' },
|
|
|
|
|
+ { label: '当前任务', value: '0' },
|
|
|
|
|
+ { label: '历史任务', value: '1' }
|
|
|
|
|
+])
|
|
|
|
|
+// 0连接中 3 等待中 4 已暂停 5 处理中 6已停止 7已取消 8已中止 9已完成
|
|
|
|
|
+const jobStatus: any = ref([
|
|
|
|
|
+ { label: '连接中', value: '0', color: 'primary' },
|
|
|
|
|
+ { label: '等待中', value: '3', color: 'info' },
|
|
|
|
|
+ { label: '已暂停', value: '4', color: 'info' },
|
|
|
|
|
+ { label: '处理中', value: '5', color: 'primary' },
|
|
|
|
|
+ { label: '已停止', value: '6', color: 'danger' },
|
|
|
|
|
+ { label: '已取消', value: '7', color: 'danger' },
|
|
|
|
|
+ { label: '已中止', value: '8', color: 'danger' },
|
|
|
|
|
+ { label: '已完成', value: '9', color: 'success' },
|
|
|
|
|
+])
|
|
|
|
|
+const dataList = ref([])
|
|
|
|
|
+const currentData: any = ref({})
|
|
|
|
|
+// 加载中: loading; 没有数据: finished; 错误: error;
|
|
|
|
|
+const loadStatus: any = ref('loading')
|
|
|
|
|
+// 动作面板
|
|
|
|
|
+const isShowActions = ref(false)
|
|
|
|
|
+const actionsTitle = ref('')
|
|
|
|
|
+const currentActions: any = ref([{ loading: true }])
|
|
|
|
|
+const isToTop = ref(false)
|
|
|
|
|
+// 文件类型
|
|
|
|
|
+const imageSrc = '/static/images/image.png'
|
|
|
|
|
+const docSrc = '/static/images/doc.png'
|
|
|
|
|
+const xlsSrc = '/static/images/xls.png'
|
|
|
|
|
+const pptSrc = '/static/images/ppt.png'
|
|
|
|
|
+const pdfSrc = '/static/images/pdf.png'
|
|
|
|
|
+const txtSrc = '/static/images/txt.png'
|
|
|
|
|
+const otherSrc = '/static/images/other.png'
|
|
|
|
|
+
|
|
|
|
|
+defineOptions({
|
|
|
|
|
+ name: 'Job',
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 根据文件类型获取图片
|
|
|
|
|
+// 允许的文件类型 allowType = ['txt', 'pdf', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'pptx', 'gif', 'png', 'jpg', 'jpeg', 'webp']
|
|
|
|
|
+function getFileType(fileName) {
|
|
|
|
|
+ let src = otherSrc
|
|
|
|
|
+ let fileType = ""
|
|
|
|
|
+ const lastIndex = fileName.lastIndexOf('.')
|
|
|
|
|
+ if (lastIndex != -1) fileType = fileName.substring(lastIndex + 1)
|
|
|
|
|
+ switch (fileType) {
|
|
|
|
|
+ case "doc":
|
|
|
|
|
+ case "docx":
|
|
|
|
|
+ src = docSrc
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "xls":
|
|
|
|
|
+ case "xlsx":
|
|
|
|
|
+ src = xlsSrc;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "ppt":
|
|
|
|
|
+ case "pptx":
|
|
|
|
|
+ src = pptSrc;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "png":
|
|
|
|
|
+ case "jpg":
|
|
|
|
|
+ case "jpeg":
|
|
|
|
|
+ case "gif":
|
|
|
|
|
+ case "webp":
|
|
|
|
|
+ src = imageSrc;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "txt":
|
|
|
|
|
+ src = txtSrc;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case "pdf":
|
|
|
|
|
+ src = pdfSrc;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ return src
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 根据状态 构造操作面板
|
|
|
|
|
+function buildCurrentActions() {
|
|
|
|
|
+ currentActions.value = [
|
|
|
|
|
+ { name: '查看' },
|
|
|
|
|
+ { name: '重打' },
|
|
|
|
|
+ { name: '取消' },
|
|
|
|
|
+ { name: '删除', color: '#fa4350' }
|
|
|
|
|
+ ]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取列表数据
|
|
|
|
|
+function getDataList() {
|
|
|
|
|
+ loadStatus.value = 'loading'
|
|
|
|
|
+ const params = { ...queryParams }
|
|
|
|
|
+ if (params.title) {
|
|
|
|
|
+ params.title = '*' + params.title + '*'
|
|
|
|
|
+ } else {
|
|
|
|
|
+ delete params.title
|
|
|
|
|
+ }
|
|
|
|
|
+ if (params.completed === '' || params.completed === 'all') delete params.completed
|
|
|
|
|
+ if (!params.printer) delete params.printer
|
|
|
|
|
+ getUserHubJobsPage(params)
|
|
|
|
|
+ .then((res: any) => {
|
|
|
|
|
+ if (res.code === 0 && res.body) {
|
|
|
|
|
+ total.value = res.body.total
|
|
|
|
|
+ if (queryParams.pageNo === 1) {
|
|
|
|
|
+ dataList.value = res.body.records || []
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dataList.value.push(...(res.body.records || []))
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((e) => {})
|
|
|
|
|
+ .finally(() => {
|
|
|
|
|
+ loadStatus.value = 'finished'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const onSearch = debounce(() => {
|
|
|
|
|
+ queryParams.pageNo = 1
|
|
|
|
|
+ getDataList()
|
|
|
|
|
+}, 500)
|
|
|
|
|
+
|
|
|
|
|
+// 查看详情
|
|
|
|
|
+function toDetail(id: string) {
|
|
|
|
|
+ uni.navigateTo({
|
|
|
|
|
+ url: `/pages/print/jobDetail?id=${id}`,
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 重打任务
|
|
|
|
|
+function handleReprint(id: string) {
|
|
|
|
|
+ reprintUserHubJobs({id}).then((res: any) => {
|
|
|
|
|
+ if (res.code === 0) {
|
|
|
|
|
+ toast.success('已发送重新打印')
|
|
|
|
|
+ getDataList()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
|
+ console.log(error)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 取消任务
|
|
|
|
|
+function handleCancel(id: string) {
|
|
|
|
|
+ cancelUserHubJobs({id}).then((res: any) => {
|
|
|
|
|
+ if (res.code === 0) {
|
|
|
|
|
+ toast.success('取消打印任务成功')
|
|
|
|
|
+ getDataList()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
|
+ console.log(error)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 删除任务
|
|
|
|
|
+function handleDelete(item) {
|
|
|
|
|
+ message
|
|
|
|
|
+ .confirm({
|
|
|
|
|
+ title: '提示',
|
|
|
|
|
+ msg: `是否删除打印任务: ${item.title} ?`,
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ deleteUserHubJobs(item.id)
|
|
|
|
|
+ .then((res: any) => {
|
|
|
|
|
+ if (res.code === 0) {
|
|
|
|
|
+ toast.success('删除成功')
|
|
|
|
|
+ queryParams.pageNo = 1
|
|
|
|
|
+ getDataList()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
|
+ console.log(error)
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
|
+ console.log(error)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 显示操作
|
|
|
|
|
+function showActions(data: any) {
|
|
|
|
|
+ actionsTitle.value = data.title ? `打印任务: ${data.title}` : '操作'
|
|
|
|
|
+ currentData.value = data || {}
|
|
|
|
|
+ buildCurrentActions()
|
|
|
|
|
+ isShowActions.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 处理操作
|
|
|
|
|
+function selectActions(data: any) {
|
|
|
|
|
+ switch (data.item.name) {
|
|
|
|
|
+ case '查看':
|
|
|
|
|
+ toDetail(currentData.value.id)
|
|
|
|
|
+ break
|
|
|
|
|
+ case '重打':
|
|
|
|
|
+ handleReprint(currentData.value.id)
|
|
|
|
|
+ break
|
|
|
|
|
+ case '取消':
|
|
|
|
|
+ handleCancel(currentData.value.id)
|
|
|
|
|
+ break
|
|
|
|
|
+ case '删除':
|
|
|
|
|
+ handleDelete(currentData.value)
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 查询列表, 滚动到顶部, 返回第一页
|
|
|
|
|
+function resetDataList() {
|
|
|
|
|
+ uni.pageScrollTo({
|
|
|
|
|
+ scrollTop: 0,
|
|
|
|
|
+ duration: 300,
|
|
|
|
|
+ })
|
|
|
|
|
+ dataList.value = []
|
|
|
|
|
+ onSearch()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 页面加载
|
|
|
|
|
+onLoad((option) => {
|
|
|
|
|
+ // 指定打印机
|
|
|
|
|
+ if (option && option.printer) queryParams.printer = option.printer
|
|
|
|
|
+ getDataList()
|
|
|
|
|
+ // 监听刷新
|
|
|
|
|
+ uni.$on('refreshData', () => {
|
|
|
|
|
+ resetDataList()
|
|
|
|
|
+ isToTop.value = true
|
|
|
|
|
+ })
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 页面显示
|
|
|
|
|
+onShow(() => {
|
|
|
|
|
+ if (isToTop.value) {
|
|
|
|
|
+ uni.pageScrollTo({
|
|
|
|
|
+ scrollTop: 0,
|
|
|
|
|
+ duration: 300,
|
|
|
|
|
+ })
|
|
|
|
|
+ isToTop.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 滚动到底部
|
|
|
|
|
+onReachBottom(() => {
|
|
|
|
|
+ if (dataList.value.length < total.value) {
|
|
|
|
|
+ queryParams.pageNo++
|
|
|
|
|
+ getDataList()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ loadStatus.value = 'finished'
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.sticky-box {
|
|
|
|
|
+ width: 100vw;
|
|
|
|
|
+ height: 100rpx;
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+}
|
|
|
|
|
+.search-type {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ height: 60rpx;
|
|
|
|
|
+ padding: 0 16rpx 0 32rpx;
|
|
|
|
|
+ line-height: 60rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.search-type::after {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 10rpx;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 10rpx;
|
|
|
|
|
+ width: 2rpx;
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.25);
|
|
|
|
|
+}
|
|
|
|
|
+.search-type {
|
|
|
|
|
+ :deep(.icon-arrow) {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ font-size: 40rpx;
|
|
|
|
|
+ vertical-align: middle;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.printer {
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.list-contain {
|
|
|
|
|
+ padding: 10rpx 30rpx 30rpx;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+
|
|
|
|
|
+ .item-contain {
|
|
|
|
|
+ padding: 30rpx;
|
|
|
|
|
+ margin-bottom: 30rpx;
|
|
|
|
|
+ border: 2rpx solid #eee;
|
|
|
|
|
+
|
|
|
|
|
+ .item-info {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ .image {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ padding-right: 14rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ .name {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ .main-text {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ word-break: break-all;
|
|
|
|
|
+ }
|
|
|
|
|
+ .sub-text {
|
|
|
|
|
+ margin-top: 14rpx;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #00000073;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .opt {
|
|
|
|
|
+ width: 80rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .item-opt {
|
|
|
|
|
+ margin-top: 20rpx;
|
|
|
|
|
+ border-top: 2rpx solid #eee;
|
|
|
|
|
+ padding-top: 20rpx;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+
|
|
|
|
|
+ .opt-btn {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ padding: 4rpx 20rpx;
|
|
|
|
|
+ margin-left: 20rpx;
|
|
|
|
|
+ color: var(--wot-color-theme);
|
|
|
|
|
+ border: 2rpx solid var(--wot-color-theme);
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ }
|
|
|
|
|
+ .opt-btn:first-of-type {
|
|
|
|
|
+ margin-left: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .delete-btn {
|
|
|
|
|
+ color: #fa4350;
|
|
|
|
|
+ border-color: #fa4350;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+//搜索下拉菜单
|
|
|
|
|
+:deep(.search-menu .wd-drop-menu__list) {
|
|
|
|
|
+ background: none;
|
|
|
|
|
+}
|
|
|
|
|
+:deep(.search-menu .wd-drop-menu__item) {
|
|
|
|
|
+ height: 62rpx;
|
|
|
|
|
+ line-height: 62rpx;
|
|
|
|
|
+}
|
|
|
|
|
+:deep(.search-menu .wd-drop-menu__item-title::after) {
|
|
|
|
|
+ content: none;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|