| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <template>
- <div class="store-page service-page">
- <div class="service-page__inner service-page__inner--wide">
- <Breadcrumb />
- <header class="page-header">
- <div>
- <h1 class="store-section-title">我的工单</h1>
- <p class="store-section-desc">查看售后处理进度与历史沟通记录</p>
- </div>
- <a-button type="primary" class="submit-btn" @click="$router.push('/service/createOrder')">
- <template #icon><icon-plus /></template>
- 提交工单
- </a-button>
- </header>
- <a-alert v-if="notice" type="info" closable class="notice">{{ notice }}</a-alert>
- <a-spin :loading="loading" class="store-spin">
- <a-empty v-if="!loading && data.length === 0" description="暂无工单">
- <a-button type="primary" @click="$router.push('/service/createOrder')">去提交</a-button>
- </a-empty>
- <div v-else class="ticket-list">
- <article
- v-for="record in data"
- :key="record.id"
- class="ticket-card"
- @click="$router.push(`/service/orderDetail/${record.id}`)"
- >
- <div class="ticket-card__head">
- <span class="ticket-id">#{{ record.id }}</span>
- <WorkOrderStateTag :state="record.state" />
- </div>
- <h3 class="ticket-card__title">{{ record.title }}</h3>
- <div class="ticket-card__meta">
- <span><icon-email /> {{ record.email }}</span>
- <span><icon-clock-circle /> {{ formatTime(record.update_time) }}</span>
- </div>
- <div class="ticket-card__action">
- <a-button type="text" size="small" @click.stop="$router.push(`/service/orderDetail/${record.id}`)">
- 查看详情
- </a-button>
- </div>
- </article>
- </div>
- <div v-if="pagination.total > pagination.pagesize" class="pager">
- <a-pagination
- :total="pagination.total"
- :current="pagination.current"
- :page-size="pagination.pagesize"
- show-total
- show-page-size
- @change="handlePageChange"
- @page-size-change="handlePageSizeChange"
- />
- </div>
- </a-spin>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, reactive, onMounted } from 'vue'
- import { orderList } from '@/api/workOrder'
- import { Notification } from '@arco-design/web-vue'
- import { useRoute } from 'vue-router'
- import { getNotice } from '@/utils/util'
- import { formatStoreTime } from '@/utils/storeFormat'
- import WorkOrderStateTag from '@/components/service/WorkOrderStateTag.vue'
- const notice = ref('')
- const loading = ref(false)
- const data = ref([])
- const pagination = reactive({ total: 0, current: 1, pagesize: 15 })
- const formatTime = (time) => formatStoreTime(time)
- const getOrderList = async () => {
- try {
- loading.value = true
- const res = await orderList({
- pagesize: pagination.pagesize,
- current: pagination.current
- })
- if (!res || res.code !== 0) {
- return Notification.error({
- title: '获取工单失败',
- content: res?.msg ?? '请稍后再试'
- })
- }
- data.value = res.data ?? []
- pagination.total = res.pagination?.total ?? 0
- } catch (error) {
- Notification.error({
- title: '获取工单失败',
- content: error.message || '请稍后再试'
- })
- } finally {
- loading.value = false
- }
- }
- const handlePageChange = (page) => {
- pagination.current = page
- getOrderList()
- }
- const handlePageSizeChange = (size) => {
- pagination.pagesize = size
- pagination.current = 1
- getOrderList()
- }
- const GetNotice = async () => {
- const { path } = useRoute()
- notice.value = await getNotice(path)
- }
- onMounted(() => {
- getOrderList()
- GetNotice()
- })
- </script>
- <style lang="less" scoped>
- @import '@/styles/store-theme.less';
- .page-header {
- display: flex;
- flex-wrap: wrap;
- align-items: flex-end;
- justify-content: space-between;
- gap: 16px;
- margin-bottom: 20px;
- }
- .submit-btn {
- border-radius: 999px;
- background: @store-primary !important;
- border-color: @store-primary !important;
- }
- .notice {
- margin-bottom: 16px;
- border-radius: @store-radius-sm;
- }
- .ticket-list {
- display: flex;
- flex-direction: column;
- gap: 12px;
- width: 100%;
- }
- .ticket-card {
- width: 100%;
- box-sizing: border-box;
- background: @store-card-bg;
- border: 1px solid @store-card-border;
- border-radius: @store-radius;
- padding: 16px 20px;
- cursor: pointer;
- transition: box-shadow 0.2s, border-color 0.2s;
- &:hover {
- box-shadow: @store-shadow;
- border-color: fade(@store-accent, 40%);
- }
- &__head {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 10px;
- }
- .ticket-id {
- font-size: 0.8rem;
- color: @store-text-muted;
- font-family: ui-monospace, monospace;
- }
- &__title {
- margin: 0 0 10px;
- font-size: 1.05rem;
- font-weight: 600;
- color: @store-primary;
- }
- &__meta {
- display: flex;
- flex-wrap: wrap;
- gap: 16px;
- font-size: 0.85rem;
- color: @store-text-muted;
- span {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- }
- }
- &__action {
- margin-top: 12px;
- display: flex;
- justify-content: flex-end;
- }
- }
- .pager {
- margin-top: 20px;
- display: flex;
- justify-content: center;
- }
- </style>
|