| src/api/collaborativeApproval/noticeManagement.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/login.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/manifest.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/cooperativeOffice/noticeManagement/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/inspectionUpload/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/pages/productionManagement/productionReporting/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/collaborativeApproval/noticeManagement.js
@@ -3,7 +3,7 @@ // æ¥è¯¢å ¬åå表 export function listNotice(query) { return request({ url: '/collaborativeApproval/notice/list', url: '/collaborativeApproval/notice/page', method: 'get', params: query }) @@ -20,7 +20,7 @@ // æ°å¢å ¬å export function addNotice(data) { return request({ url: '/collaborativeApproval/notice', url: '/collaborativeApproval/notice/add', method: 'post', data: data }) @@ -29,41 +29,24 @@ // ä¿®æ¹å ¬å export function updateNotice(data) { return request({ url: '/collaborativeApproval/notice', url: '/collaborativeApproval/notice/update', method: 'put', data: data }) } // å é¤å ¬å export function delNotice(noticeId) { export function delNotice(ids) { return request({ url: '/collaborativeApproval/notice/' + noticeId, method: 'delete' }) } // æ¹éå é¤å ¬å export function delNoticeBatch(noticeIds) { return request({ url: '/collaborativeApproval/notice/batch', url: '/collaborativeApproval/notice/' + ids, method: 'delete', data: noticeIds }) } // åå¸å ¬å export function publishNotice(noticeId) { // è·åå ¬åæ°é export function getCount() { return request({ url: '/collaborativeApproval/notice/publish/' + noticeId, method: 'put' }) } // ä¸çº¿å ¬å export function offlineNotice(noticeId) { return request({ url: '/collaborativeApproval/notice/offline/' + noticeId, method: 'put' url: '/collaborativeApproval/notice/count', method: 'get', }) } src/api/login.js
@@ -40,4 +40,13 @@ method: 'get', params: params }) } // è·åæªè¿æå ¬åæ°é export function noticesList(params) { return request({ url: '/collaborativeApproval/notice/page', method: 'get', params: params }) } src/manifest.json
@@ -1,12 +1,16 @@ { "name" : "ä¿¡æ¯ç®¡ç", "appid" : "__UNI__D950DA4", "appid" : "__UNI__E1C100D", "description" : "", "versionName" : "1.0.0", "versionCode" : "100", "transformPx" : false, /* 5+Appç¹æç¸å ³ */ "app-plus" : { "compatible" : { "usingComponents" : true, "ignoreVersion" : true }, "usingComponents" : true, "nvueStyleCompiler" : "uni-app", "compilerVersion" : 3, @@ -19,7 +23,8 @@ /* 模åé ç½® */ "modules" : { "Camera" : {}, "Barcode" : {} "Barcode" : {}, "Push" : {} }, /* åºç¨åå¸ä¿¡æ¯ */ "distribute" : { @@ -48,7 +53,17 @@ "dSYMs" : false }, /* SDKé ç½® */ "sdkConfigs" : {}, "sdkConfigs" : { "push" : { "unipush" : { "icons" : { "small" : { "ldpi" : "D:/xindao/wenjian/img/logo/app.png" } } } } }, "icons" : { "android" : { "hdpi" : "unpackage/res/icons/72x72.png", src/pages.json
@@ -317,6 +317,13 @@ } }, { "path": "pages/cooperativeOffice/noticeManagement/index", "style": { "navigationBarTitleText": "éç¥å ¬å", "navigationStyle": "custom" } }, { "path": "pages/equipmentManagement/ledger/index", "style": { "navigationBarTitleText": "设å¤å°è´¦", @@ -411,7 +418,9 @@ "path": "pages/inspectionUpload/index", "style": { "navigationBarTitleText": "å·¡æ£ä¸ä¼ ", "navigationStyle": "custom" "navigationStyle": "custom", "enablePullDownRefresh": true, "backgroundColor": "#f8f8f8" } }, { src/pages/cooperativeOffice/noticeManagement/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,813 @@ <template> <view class="notice-page"> <PageHeader title="éç¥å ¬å" @back="goBack" /> <!-- æç´¢è¡¨å --> <!-- <view class="search_form"> <up-button type="primary" size="small" @click="openForm('add')">æ°å¢å ¬å</up-button> <up-button type="error" size="small" plain @click="handleDeleteBatch" :disabled="!selectedIds.length"> å é¤ </up-button> </view> --> <!-- éç¥å ¬åæ¿ --> <view class="notice-board"> <!-- ç»ä¸éç¥åºå --> <view class="notice-section" v-if="totalNoticeCount > 0"> <view class="section-header"> <h3>� éç¥å ¬å</h3> <text class="section-count">{{ totalNoticeCount }}æ¡</text> </view> <view class="notice-cards"> <!-- æ¾åéç¥ --> <view v-for="notice in holidayNotices" :key="'holiday-' + notice.id" class="notice-card holiday-card" :class="{ 'urgent': notice.priority === '3' }" > <view class="card-header"> <view class="card-title"> <view class="holiday-icon"> <up-icon name="calendar" size="18" color="#67c23a" /> </view> <text>{{ notice.title }}</text> </view> <!-- <view class="card-actions">--> <!-- <up-button--> <!-- text--> <!-- type="primary"--> <!-- size="mini"--> <!-- @click="handleEdit(notice)"--> <!-- :disabled="isNoticeExpired(notice)"--> <!-- >--> <!-- ç¼è¾--> <!-- </up-button>--> <!-- <up-button--> <!-- text--> <!-- type="error"--> <!-- size="mini"--> <!-- @click="handleDelete(notice.id)"--> <!-- >--> <!-- å é¤--> <!-- </up-button>--> <!-- </view>--> </view> <view class="card-content"> <text>{{ notice.content }}</text> </view> <view class="card-footer"> <view class="card-meta"> <text class="type" :class="'type-' + notice.type"> {{ notice.type }} </text> <text class="priority" :class="'priority-' + notice.priority"> {{ getPriorityText(notice.priority) }} </text> <text class="status" :class="'status-' + getNoticeStatus(notice)"> {{ getStatusText(getNoticeStatus(notice)) }} </text> </view> <view class="card-info"> <text class="creator">{{ notice.createUserName }}</text> <text class="expiration" v-if="notice.expirationDate">æªæ¢æ¥æï¼{{ notice.expirationDate }}</text> </view> </view> <view class="card-remark" v-if="notice.remark"> <up-icon name="info-circle" size="16" color="#409eff" /> <text>{{ notice.remark }}</text> </view> </view> <!-- 设å¤ç»´ä¿®éç¥ --> <view v-for="notice in maintenanceNotices" :key="'maintenance-' + notice.id" class="notice-card maintenance-card" :class="{ 'urgent': notice.priority === '3' }" > <view class="card-header"> <view class="card-title"> <view class="maintenance-icon"> <up-icon name="wrench" size="18" color="#e6a23c" /> </view> <text>{{ notice.title }}</text> </view> <view class="card-actions"> <up-button text type="primary" size="mini" @click="handleEdit(notice)" :disabled="isNoticeExpired(notice)" > ç¼è¾ </up-button> <up-button text type="error" size="mini" @click="handleDelete(notice.id)" > å é¤ </up-button> </view> </view> <view class="card-content"> <text>{{ notice.content }}</text> </view> <view class="card-footer"> <view class="card-meta"> <text class="priority" :class="'priority-' + notice.priority"> {{ getPriorityText(notice.priority) }} </text> <text class="status" :class="'status-' + getNoticeStatus(notice)"> {{ getStatusText(getNoticeStatus(notice)) }} </text> </view> <view class="card-info"> <text class="creator">{{ notice.createUserName }}</text> <text class="expiration" v-if="notice.expirationDate">æªæ¢æ¥æï¼{{ notice.expirationDate }}</text> </view> </view> <view class="card-remark" v-if="notice.remark"> <up-icon name="info-circle" size="16" color="#409eff" /> <text>{{ notice.remark }}</text> </view> </view> </view> </view> <!-- ç©ºç¶æ --> <view class="empty-state" v-if="holidayNotices.length === 0 && maintenanceNotices.length === 0"> <text>ææ éç¥å ¬å</text> </view> </view> <!-- æ°å¢/ç¼è¾å¼¹çª --> <up-popup v-model:show="dialogVisible" mode="bottom" :round="18" :safeAreaInsetBottom="true" @close="resetForm" > <view class="dialog-container"> <view class="dialog-header"> <text class="dialog-title">{{ dialogTitle }}</text> </view> <view class="dialog-body"> <up-form ref="formRef" :model="form" :rules="rules" labelWidth="80" > <up-form-item label="å ¬åæ é¢" prop="title"> <up-input v-model="form.title" placeholder="请è¾å ¥å ¬åæ é¢" /> </up-form-item> <up-form-item label="å ¬åç±»å" prop="type"> <up-input v-model="form.type" placeholder="请è¾å ¥å ¬åç±»å" /> </up-form-item> <up-form-item label="ç¶æ"> <up-radio-group v-model="form.status"> <up-radio :name="0">è稿</up-radio> <up-radio :name="1">æ£å¼åå¸</up-radio> </up-radio-group> </up-form-item> <up-form-item label="ä¼å 级" prop="priority"> <up-select v-model="form.priority" :options="priorityOptions" placeholder="è¯·éæ©ä¼å 级" /> </up-form-item> <up-form-item label="è¿ææ¶é´" prop="expirationDate"> <up-datetime-picker v-model="form.expirationDate" mode="date" @confirm="onExpireConfirm" > <up-input :value="form.expirationDate" placeholder="è¯·éæ©æ¥æ" readonly /> </up-datetime-picker> </up-form-item> <up-form-item label="å ¬åå 容" prop="content"> <up-textarea v-model="form.content" placeholder="请è¾å ¥å ¬åå 容" :maxlength="500" count /> </up-form-item> <up-form-item label="夿³¨"> <up-textarea v-model="form.remark" placeholder="请è¾å ¥å¤æ³¨ä¿¡æ¯" :maxlength="200" count /> </up-form-item> </up-form> </view> <view class="dialog-footer"> <up-button text="åæ¶" type="info" plain @click="dialogVisible = false" :customStyle="{ marginRight: '10px', flex: 1 }" /> <up-button text="ç¡®å®" type="primary" @click="submitForm" :customStyle="{ flex: 1 }" /> </view> </view> </up-popup> </view> </template> <script setup> import { onMounted, ref, reactive, toRefs } from "vue"; import { onReachBottom } from "@dcloudio/uni-app"; import PageHeader from "@/components/PageHeader.vue"; import useUserStore from "@/store/modules/user"; import { addNotice, delNotice, getCount, listNotice, updateNotice } from "@/api/collaborativeApproval/noticeManagement.js"; const userStore = useUserStore(); // ååºå¼æ°æ® const data = reactive({ searchForm: { title: "", type: undefined, status: undefined, }, form: { id: undefined, title: "", type: null, content: "", status: 0, priority: 1, remark: "", expirationDate: "", }, rules: { title: [ {required: true, message: "å ¬åæ é¢ä¸è½ä¸ºç©º", trigger: "blur"} ], type: [ {required: true, message: "è¯·éæ©å ¬åç±»å", trigger: "change"} ], content: [ {required: true, message: "å ¬åå 容ä¸è½ä¸ºç©º", trigger: "blur"} ], expirationDate: [ {required: true, message: "è¯·éæ©æ¥æ", trigger: "change"} ] } }); const {searchForm, form, rules} = toRefs(data); // 页é¢ç¶æ const dialogVisible = ref(false); const dialogTitle = ref(""); const selectedIds = ref([]); const formRef = ref(); const priorityOptions = [ { label: "æ®é", value: 1 }, { label: "éè¦", value: 2 }, { label: "ç´§æ¥", value: 3 }, ]; const goBack = () => { uni.navigateBack(); }; const onExpireConfirm = (e) => { if (!e) return; // uview-plus datetime-picker confirm äºä»¶è¿åç value const value = e.value || e; form.value.expirationDate = value; }; const getPriorityText = (priority) => { const priorityMap = {"1": "æ®é", "2": "éè¦", "3": "ç´§æ¥"}; return priorityMap[priority] || "æ®é"; }; const getStatusText = (status) => { const statusMap = {"0": "è稿", "1": "å·²åå¸", "2": "å·²è¿æ"}; return statusMap[status] || "æªç¥"; }; const isNoticeExpired = (notice) => { if (!notice || !notice.expirationDate) { return false; } const expiration = new Date(notice.expirationDate); if (Number.isNaN(expiration.getTime())) { return false; } expiration.setHours(23, 59, 59, 999); return new Date() > expiration; }; const getNoticeStatus = (notice) => { const normalizedStatus = notice && notice.status !== undefined && notice.status !== null ? String(notice.status) : "0"; return isNoticeExpired(notice) ? "2" : normalizedStatus; }; const openForm = (type) => { if (type === 'add') { dialogTitle.value = "æ°å¢å ¬å"; form.value = { id: undefined, title: "", type: undefined, content: "", status: 0, priority: 1, remark: "", expirationDate: "", }; } dialogVisible.value = true; }; const handleEdit = (row) => { if (isNoticeExpired(row)) { uni.showToast({ title: "å·²è¿æçå ¬åä¸å¯ç¼è¾", icon: "none" }); return; } dialogTitle.value = "ç¼è¾å ¬å"; form.value = {...row}; dialogVisible.value = true; }; const handleDelete = (id) => { if (!id) return; uni.showModal({ title: "æç¤º", content: "确认å é¤è¿æ¡å ¬ååï¼", success: (res) => { if (res.confirm) { delNotice(id).then(() => { uni.showToast({ title: "å 餿å", icon: "success" }); resetTable(); }); } } }); }; // é¢çæ¹éå é¤ï¼ç®åæªå®ç°éä¸é»è¾ï¼ä» å ä½ï¼ const handleDeleteBatch = () => { if (!selectedIds.value.length) return; uni.showModal({ title: "æç¤º", content: "确认å é¤éä¸çå ¬ååï¼", success: (res) => { if (res.confirm) { // æ ¹æ®selectedIdsæ§è¡æ¹éå é¤é»è¾ï¼å¯æéæ©å±ï¼ } } }); }; const submitForm = () => { formRef.value.validate((valid) => { if (valid) { if (form.value.id) { // ç¼è¾æ¨¡å¼ updateNotice(form.value).then(res => { uni.showToast({ title: "ä¿®æ¹æå", icon: "success" }); resetTable(); }) } else { // æ°å¢æ¨¡å¼ addNotice(form.value).then(res => { uni.showToast({ title: "æ°å¢æå", icon: "success" }); resetTable(); }) } dialogVisible.value = false; } }); }; const totalNoticeCount = ref(0) const fetchCount = () => { getCount().then(res => { totalNoticeCount.value = res.data.reduce((total, item) => total + item.count, 0); }); } const holidayNotices = ref([]) const maintenanceNotices = ref([]) const holidayNoticePage = ref({ total: 0, current: 1, size: 9 }) const maintenanceNoticePage = ref({ total: 0, current: 1, size: 9 }) const isLoadingMore = ref(false) const fetchHolidayNotices = (append = false) => { listNotice({...holidayNoticePage.value}).then(res => { const records = res?.data?.records || [] holidayNoticePage.value.total = res?.data?.total || 0 if (append && holidayNotices.value.length) { holidayNotices.value = [...holidayNotices.value, ...records] } else { holidayNotices.value = records } }); }; const fetchMaintenanceNotices = (append = false) => { listNotice({...holidayNoticePage.value, type: 2}).then(res => { const records = res?.data?.records || [] maintenanceNoticePage.value.total = res?.data?.total || 0 if (append && maintenanceNotices.value.length) { maintenanceNotices.value = [...maintenanceNotices.value, ...records] } else { maintenanceNotices.value = records } }); }; const handleCurrentChange = (val) => { holidayNoticePage.value.size = val.limit holidayNoticePage.value.current = val.page maintenanceNoticePage.value.size = val.limit maintenanceNoticePage.value.current = val.page fetchHolidayNotices() fetchMaintenanceNotices() }; const resetTable = () => { holidayNoticePage.value.current = 1 holidayNoticePage.value.size = 9 maintenanceNoticePage.value.current = 1 maintenanceNoticePage.value.size = 9 fetchHolidayNotices() fetchMaintenanceNotices() fetchCount() }; const resetForm = () => { formRef.value?.resetFields(); }; // çå½å¨æ onMounted(() => { fetchCount() fetchHolidayNotices() fetchMaintenanceNotices() }); // ä¸åå è½½æ´å¤ onReachBottom(() => { if (isLoadingMore.value) return; isLoadingMore.value = true; holidayNoticePage.value.current += 1; maintenanceNoticePage.value.current += 1; Promise.all([ new Promise((resolve) => { fetchHolidayNotices(true); resolve(); }), new Promise((resolve) => { fetchMaintenanceNotices(true); resolve(); }) ]).finally(() => { isLoadingMore.value = false; }); }); </script> <style scoped> .notice-page { min-height: 100vh; background: #f5f7fa; padding-bottom: 16px; display: flex; flex-direction: column; } .search_form { background: #ffffff; padding: 12px 16px; margin: 8px 12px 12px; border-radius: 10px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); display: flex; justify-content: flex-start; align-items: center; } .search_title { font-weight: 500; color: #333; margin-right: 8px; } .ml10 { margin-left: 10px; } .notice-board { padding: 0 12px 16px; } .notice-section { margin-bottom: 16px; } .section-header { display: flex; align-items: center; margin: 4px 4px 12px; } .section-header h3 { margin: 0; color: #303133; font-size: 16px; font-weight: 600; } .section-count { margin-left: 10px; background: #409eff; color: white; padding: 2px 8px; border-radius: 12px; font-size: 12px; } .notice-cards { display: flex; flex-direction: column; gap: 12px; } .notice-card { background: white; border-radius: 12px; padding: 14px 14px 10px; box-shadow: 0 4px 10px rgba(15, 23, 42, 0.06); transition: all 0.3s ease; border-left: 4px solid transparent; } .notice-card:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); } .holiday-card { border-left-color: #67c23a; } .maintenance-card { border-left-color: #e6a23c; } .urgent { border-left-color: #f56c6c; background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%); } .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; } .card-title { display: flex; align-items: center; font-size: 15px; font-weight: 600; color: #303133; flex: 1; } .holiday-icon { color: #67c23a; margin-right: 8px; font-size: 18px; } .maintenance-icon { color: #e6a23c; margin-right: 8px; font-size: 18px; } .card-actions { display: flex; gap: 8px; } .card-content { margin-bottom: 10px; } .card-content text { color: #606266; line-height: 1.6; font-size: 13px; } .card-footer { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .card-meta { display: flex; gap: 8px; } .type, .priority, .status { padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; } .type-1 { background: #f0f9ff; color: #0369a1; } .type-2 { background: #fef3c7; color: #d97706; } .priority-1 { background: #f0f9ff; color: #0369a1; } .priority-2 { background: #fef3c7; color: #d97706; } .priority-3 { background: #fef2f2; color: #dc2626; } .status-0 { background: #f3f4f6; color: #6b7280; } .status-1 { background: #d1fae5; color: #059669; } .status-2 { background: #fef3c7; color: #d97706; } .card-info { display: flex; flex-direction: column; align-items: flex-end; font-size: 12px; color: #909399; } .creator { font-weight: 500; margin-bottom: 2px; } .expiration { margin-top: 2px; } .card-remark { display: flex; align-items: center; gap: 6px; padding: 8px 12px; background: #f8f9fa; border-radius: 6px; font-size: 12px; color: #606266; border-left: 3px solid #409eff; } .empty-state { text-align: center; padding: 48px 16px; color: #999; font-size: 13px; } .dialog-footer { text-align: right; } /* ç§»å¨ç«¯å¼¹çªæ ·å¼ */ .dialog-container { background: #ffffff; border-radius: 18px 18px 0 0; max-height: 80vh; display: flex; flex-direction: column; } .dialog-header { padding: 16px 20px 8px 20px; } .dialog-title { font-size: 16px; font-weight: 600; color: #303133; } .dialog-body { flex: 1; padding: 0 16px 12px 16px; overflow-y: auto; } .dialog-footer { display: flex; padding: 12px 16px 16px 16px; border-top: 1px solid #f0f0f0; } /* ååºå¼è®¾è®¡ */ @media (max-width: 768px) { .search_form { flex-direction: column; gap: 15px; align-items: flex-start; } .search_form > div { width: 100%; display: flex; gap: 10px; } } </style> src/pages/index.vue
@@ -2,12 +2,12 @@ <view class="content"> <view class="header-section"> <view class="currentFactory"> <up-text type="primary" :text="userStore.currentFactoryName" @click="show = true" size="18" class="factoryName" suffixIcon="arrow-right" :iconStyle="iconStyle"></up-text> <up-text type="primary" :text="userStore.currentFactoryName" @click="show = true" size="18" class="factoryName" suffixIcon="arrow-right" :iconStyle="iconStyle"></up-text> </view> <up-picker :show="show" :columns="factoryList" @confirm="changeFactory" @cancel="show = false"></up-picker> </view> <view class="hero-section"> <view class="bg-img"> <view class="hero-content"> @@ -16,7 +16,7 @@ <view class="hero-wave"></view> </view> </view> <!-- <view class="notice-section">--> <!-- <view class="notice">--> <!-- <view class="notice-content">--> @@ -31,7 +31,7 @@ <!-- </view>--> <!-- </view>--> <!-- </view>--> <!-- è¥éç®¡çæ¨¡å --> <view class="common-module marketing-module"> <view class="module-header"> @@ -40,28 +40,17 @@ </view> </view> <view class="module-content"> <up-grid :border="false" col="4" > <up-grid-item v-for="(item, index) in marketingItems" :key="index" @click="handleCommonItemClick(item)" > <up-grid :border="false" col="4"> <up-grid-item v-for="(item, index) in marketingItems" :key="index" @click="handleCommonItemClick(item)"> <view class="icon-container" :style="{ background: item.bgColor }"> <up-icon :name="item.icon" :size="58" color="#ffffff" ></up-icon> <up-icon :name="item.icon" :size="58" color="#ffffff"></up-icon> </view> <text class="item-label">{{item.label}}</text> </up-grid-item> </up-grid> </view> </view> <!-- éè´ç®¡ç模å --> <view class="common-module purchase-module"> <view class="module-header"> @@ -70,28 +59,17 @@ </view> </view> <view class="module-content"> <up-grid :border="false" col="4" > <up-grid-item v-for="(item, index) in purchaseItems" :key="index" @click="handleCommonItemClick(item)" > <up-grid :border="false" col="4"> <up-grid-item v-for="(item, index) in purchaseItems" :key="index" @click="handleCommonItemClick(item)"> <view class="icon-container" :style="{ background: item.bgColor }"> <up-icon :name="item.icon" :size="58" color="#ffffff" ></up-icon> <up-icon :name="item.icon" :size="58" color="#ffffff"></up-icon> </view> <text class="item-label">{{item.label}}</text> </up-grid-item> </up-grid> </view> </view> <!-- åååå ¬æ¨¡å --> <view class="common-module collaboration-module"> <view class="module-header"> @@ -100,21 +78,10 @@ </view> </view> <view class="module-content"> <up-grid :border="false" col="4" > <up-grid-item v-for="(item, index) in collaborationItems" :key="index" @click="handleCommonItemClick(item)" > <up-grid :border="false" col="4"> <up-grid-item v-for="(item, index) in collaborationItems" :key="index" @click="handleCommonItemClick(item)"> <view class="icon-container" :style="{ background: item.bgColor }"> <up-icon :name="item.icon" :size="58" color="#ffffff" ></up-icon> <up-icon :name="item.icon" :size="58" color="#ffffff"></up-icon> </view> <text class="item-label">{{item.label}}</text> </up-grid-item> @@ -129,28 +96,17 @@ </view> </view> <view class="module-content"> <up-grid :border="false" col="4" > <up-grid-item v-for="(item, index) in inventoryManagement" :key="index" @click="handleCommonItemClick(item)" > <up-grid :border="false" col="4"> <up-grid-item v-for="(item, index) in inventoryManagement" :key="index" @click="handleCommonItemClick(item)"> <view class="icon-container" :style="{ background: item.bgColor }"> <up-icon :name="item.icon" :size="58" color="#ffffff" ></up-icon> <up-icon :name="item.icon" :size="58" color="#ffffff"></up-icon> </view> <text class="item-label">{{item.label}}</text> </up-grid-item> </up-grid> </view> </view> <!-- çäº§ç®¡æ§æ¨¡å --> <view class="common-module production-module"> <view class="module-header"> @@ -159,28 +115,17 @@ </view> </view> <view class="module-content"> <up-grid :border="false" col="4" > <up-grid-item v-for="(item, index) in productionItems" :key="index" @click="handleCommonItemClick(item)" > <up-grid :border="false" col="4"> <up-grid-item v-for="(item, index) in productionItems" :key="index" @click="handleCommonItemClick(item)"> <view class="icon-container" :style="{ background: item.bgColor }"> <up-icon :name="item.icon" :size="58" color="#ffffff" ></up-icon> <up-icon :name="item.icon" :size="58" color="#ffffff"></up-icon> </view> <text class="item-label">{{item.label}}</text> </up-grid-item> </up-grid> </view> </view> <!-- 设å¤ç®¡ç模å --> <view class="common-module equipment-module"> <view class="module-header"> @@ -189,21 +134,10 @@ </view> </view> <view class="module-content"> <up-grid :border="false" col="4" > <up-grid-item v-for="(item, index) in equipmentItems" :key="index" @click="handleCommonItemClick(item)" > <up-grid :border="false" col="4"> <up-grid-item v-for="(item, index) in equipmentItems" :key="index" @click="handleCommonItemClick(item)"> <view class="icon-container" :style="{ background: item.bgColor }"> <up-icon :name="item.icon" :size="58" color="#ffffff" ></up-icon> <up-icon :name="item.icon" :size="58" color="#ffffff"></up-icon> </view> <text class="item-label">{{item.label}}</text> </up-grid-item> @@ -214,1037 +148,1204 @@ </template> <script setup> import {ref, onMounted, nextTick, reactive} from 'vue'; import {userLoginFacotryList} from "@/api/login"; import modal from "@/plugins/modal"; import useUserStore from "@/store/modules/user"; import { ref, onMounted, nextTick, reactive } from 'vue'; import dayjs from "dayjs" import { userLoginFacotryList, noticesList } from "@/api/login"; import modal from "@/plugins/modal"; import useUserStore from "@/store/modules/user"; import { onShow } from '@dcloudio/uni-app' const userStore = useUserStore() const factoryId = ref(''); const show = ref(false); const factoryList = ref([]); const factoryListTem = ref([]); const iconStyle = { fontSize: '1.125rem', color: '#2979ff' } // éç¥ç¶æåæ¢ const statusList = ['éå®', 'éè´'] let statusIndex = 0 const currentStatus = ref(statusList[0]) const number = ref(7643) // 宿¶å¨åæ¢éç¥ç¶æ const startStatusTimer = () => { setInterval(() => { statusIndex = (statusIndex + 1) % statusList.length currentStatus.value = statusList[statusIndex] }, 3000) } // è¥é管çåè½æ°æ® const marketingItems = reactive([ { icon: '/static/images/icon/xiaoshoutaizhang@2x.png', label: 'éå®å°è´¦', }, { icon: '/static/images/icon/kaipiaodengji@2x.png', label: 'å¼ç¥¨ç»è®°', }, { icon: '/static/images/icon/kaipiaotaizhang@2x.png', label: 'å¼ç¥¨å°è´¦', }, { icon: '/static/images/icon/huikuandengji@2x.png', label: '忬¾ç»è®°', }, { icon: '/static/images/icon/huikuanliushui@2x.png', label: '忬¾æµæ°´', }, { icon: '/static/images/icon/kehuwanglai@2x.png', label: '客æ·å¾æ¥', const userStore = useUserStore() const factoryId = ref(''); const show = ref(false); const factoryList = ref([]); const factoryListTem = ref([]); const iconStyle = { fontSize: '1.125rem', color: '#2979ff' } ]); // éè´ç®¡çåè½æ°æ® const purchaseItems = reactive([ { icon: '/static/images/icon/caigoutaizhang@2x.png', label: 'éè´å°è´¦', }, { icon: '/static/images/icon/laipiaodengji@2x.png', label: 'æ¥ç¥¨ç»è®°', }, { icon: '/static/images/icon/laipiaotaizhang@2x.png', label: 'æ¥ç¥¨å°è´¦', }, { icon: '/static/images/icon/fukuanjingji@2x.png', label: '仿¬¾ç»è®°', }, { icon: '/static/images/icon/fukuanliushui@2x.png', label: '仿¬¾æµæ°´', }, { icon: '/static/images/icon/gongyingshangwanglai@2x.png', label: 'ä¾åºå徿¥', }, ]); // éç¥ç¶æåæ¢ const statusList = ['éå®', 'éè´'] let statusIndex = 0 const currentStatus = ref(statusList[0]) const number = ref(7643) // åååå ¬åè½æ°æ® const collaborationItems = reactive([ { icon: '/static/images/icon/gongchuguanli@2x.png', label: 'å ¬åºç®¡ç', }, { icon: '/static/images/icon/qingjiaguanli@2x.png', label: '请å管ç', }, { icon: '/static/images/icon/chuchaiguanli@2x.png', label: 'åºå·®ç®¡ç', }, { icon: '/static/images/icon/xietongshenpi@2x.png', label: 'åå审æ¹', }, { icon: '/static/images/icon/kehubaifang@2x.png', label: 'å®¢æ·æè®¿', // 宿¶å¨åæ¢éç¥ç¶æ const startStatusTimer = () => { setInterval(() => { statusIndex = (statusIndex + 1) % statusList.length currentStatus.value = statusList[statusIndex] }, 3000) } ]); // åååå ¬åè½æ°æ®inventoryManagement/receiptManagement const inventoryManagement = reactive([ { icon: '/static/images/icon/rukuguanli@2x.png', label: 'èªå®ä¹å ¥åº', }, { icon: '/static/images/icon/zidingyichuku.png', label: 'èªå®ä¹åºåº', }, ]); // ç产管æ§åè½æ°æ® const productionItems = reactive([ { icon: '/static/images/icon/shengchandingdan@2x.png', label: 'ç产订å', bgColor: '#FF9800' }, { icon: '/static/images/icon/shengchanpaigong@2x.png', label: 'ç产派工', bgColor: '#FF6B35' }, { icon: '/static/images/icon/shengchanpaichan@2x.png', label: 'å·¥åºæäº§', bgColor: '#E91E63' }, { icon: '/static/images/icon/shengchanbaogong@2x.png', label: 'ç产æ¥å·¥', bgColor: '#673AB7' }, { icon: '/static/images/icon/shengchanhesuan@2x.png', label: 'çäº§æ ¸ç®', bgColor: '#3F51B5' } ]); // 设å¤ç®¡çåè½æ°æ® const equipmentItems = reactive([ { icon: '/static/images/icon/shebeitaizhang@2x.png', label: '设å¤å°è´¦', }, { icon: '/static/images/icon/shbeibaoxiu@2x.png', label: 'è®¾å¤æ¥ä¿®', }, { icon: '/static/images/icon/shbeibaoyang@2x.png', label: '设å¤ä¿å »', }, { icon: '/static/images/icon/xunjianshangchuan@2x.png', label: 'å·¡æ£ä¸ä¼ ', }, // { // icon: '/static/images/icon/guzhangfenxi@2x.png', // label: 'åæè¿½æº¯', // bgColor: '#ff9800' // }, // { // icon: '/static/images/icon/zhinengpaidan@2x.png', // label: 'æºè½æ´¾å', // bgColor: '#ff6b35' // }, // { // icon: '/static/images/icon/zuoyezhidao@2x.png', // label: 'ä½ä¸æå¯¼', // bgColor: '#4caf50' // }, // { // icon: '/static/images/icon/jieguoyanzheng@2x.png', // label: 'ç»æéªè¯', // bgColor: '#9c27b0' // } ]); // å¤ç常ç¨åè½ç¹å» const handleCommonItemClick = (item) => { // æ ¹æ®ä¸åçåè½é¡¹è¿è¡è·³è½¬ switch (item.label) { case 'éå®å°è´¦': uni.navigateTo({ url: '/pages/sales/salesAccount/index' }); break; case 'å¼ç¥¨ç»è®°': uni.navigateTo({ url: '/pages/sales/invoicingRegistration/index' }); break; case 'å¼ç¥¨å°è´¦': uni.navigateTo({ url: '/pages/sales/invoiceLedger/index' }); break; case '忬¾ç»è®°': uni.navigateTo({ url: '/pages/sales/receiptPayment/index' }); break; case '忬¾æµæ°´': uni.navigateTo({ url: '/pages/sales/receiptPaymentHistory/index' }); break; case '客æ·å¾æ¥': uni.navigateTo({ url: '/pages/sales/receiptPaymentLedger/index' }); break; case 'éè´å°è´¦': uni.navigateTo({ url: '/pages/procurementManagement/procurementLedger/index' }); break; case 'æ¥ç¥¨ç»è®°': uni.navigateTo({ url: '/pages/procurementManagement/invoiceEntry/index' }); break; case 'æ¥ç¥¨å°è´¦': uni.navigateTo({ url: '/pages/procurementManagement/procurementInvoiceLedger/index' }); break; case '仿¬¾ç»è®°': uni.navigateTo({ url: '/pages/procurementManagement/paymentEntry/index' }); break; case '仿¬¾æµæ°´': uni.navigateTo({ url: '/pages/procurementManagement/receiptPaymentHistory/index' }); break; case 'ä¾åºå徿¥': uni.navigateTo({ url: '/pages/procurementManagement/paymentLedger/index' }); break; case 'å ¬åºç®¡ç': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index1' }); break; case '请å管ç': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index2' }); break; case 'åºå·®ç®¡ç': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index3' }); break; case 'åå审æ¹': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index' }); break; case 'å®¢æ·æè®¿': uni.navigateTo({ url: '/pages/cooperativeOffice/clientVisit/index' }); break; case 'èªå®ä¹å ¥åº': uni.navigateTo({ url: '/pages/inventoryManagement/receiptManagement/index' }); break; case 'èªå®ä¹åºåº': uni.navigateTo({ url: '/pages/inventoryManagement/issueManagement/index' }); break; case 'ç产订å': uni.navigateTo({ url: '/pages/productionManagement/productionOrder/index' }); break; case 'ç产派工': uni.navigateTo({ url: '/pages/productionManagement/productionDispatching/index' }); break; case 'å·¥åºæäº§': uni.navigateTo({ url: '/pages/productionManagement/operationScheduling/index' }); break; case 'ç产æ¥å·¥': uni.navigateTo({ url: '/pages/productionManagement/productionReporting/index' }); break; case 'çäº§æ ¸ç®': uni.navigateTo({ url: '/pages/productionManagement/productionCosting/index' }); break; case '设å¤å°è´¦': uni.navigateTo({ url: '/pages/equipmentManagement/ledger/index' }); break; case 'è®¾å¤æ¥ä¿®': uni.navigateTo({ url: '/pages/equipmentManagement/repair/index' }); break; case '设å¤ä¿å »': uni.navigateTo({ url: '/pages/equipmentManagement/upkeep/index' }); break; case 'å·¡æ£ä¸ä¼ ': uni.navigateTo({ url: '/pages/inspectionUpload/index' }); break; case 'åæè¿½æº¯': uni.navigateTo({ url: '/pages/equipmentManagement/faultAnalysis/index' }); break; case 'æºè½æ´¾å': uni.navigateTo({ url: '/pages/equipmentManagement/smartDispatch/index' }); break; case 'ä½ä¸æå¯¼': uni.navigateTo({ url: '/pages/equipmentManagement/sop/index' }); break; case 'ç»æéªè¯': uni.navigateTo({ url: '/pages/equipmentManagement/verification/index' }); break; default: uni.showToast({ title: `ç¹å»äº${item.label}`, icon: 'none' }); } }; // å建对åç»ä»¶çå¼ç¨ const uToastRef = ref(null); function getUserLoginFacotryList() { userLoginFacotryList({userName: userStore.nickName}).then(res => { // æ£æ¥res.dataæ¯å¦ä¸ºæ°ç» factoryList.value[0] = [] if (res.data && Array.isArray(res.data)) { factoryListTem.value = res.data res.data.forEach(item => { factoryList.value[0].push(item.deptName) }) factoryId.value = userStore.currentDeptId } else { // 妿res.data䏿¯æ°ç»ï¼è®¾ç½®ä¸ºç©ºæ°ç» factoryList.value = [] // è¥é管çåè½æ°æ® const marketingItems = reactive([{ icon: '/static/images/icon/xiaoshoutaizhang@2x.png', label: 'éå®å°è´¦', }, { icon: '/static/images/icon/kaipiaodengji@2x.png', label: 'å¼ç¥¨ç»è®°', }, { icon: '/static/images/icon/kaipiaotaizhang@2x.png', label: 'å¼ç¥¨å°è´¦', }, { icon: '/static/images/icon/huikuandengji@2x.png', label: '忬¾ç»è®°', }, { icon: '/static/images/icon/huikuanliushui@2x.png', label: '忬¾æµæ°´', }, { icon: '/static/images/icon/kehuwanglai@2x.png', label: '客æ·å¾æ¥', } }).catch(error => { modal.msgError('è·åå ¬å¸å表失败:', error) factoryList.value = [] }) } const changeFactory = async (arr) => { show.value = false; const factoryId = factoryListTem.value[arr.indexs[0]].deptId const loginForm = { username: userStore.name, password: uni.getStorageSync('remembered_password'), factoryId: factoryId, ]); // éè´ç®¡çåè½æ°æ® const purchaseItems = reactive([{ icon: '/static/images/icon/caigoutaizhang@2x.png', label: 'éè´å°è´¦', }, { icon: '/static/images/icon/laipiaodengji@2x.png', label: 'æ¥ç¥¨ç»è®°', }, { icon: '/static/images/icon/laipiaotaizhang@2x.png', label: 'æ¥ç¥¨å°è´¦', }, { icon: '/static/images/icon/fukuanjingji@2x.png', label: '仿¬¾ç»è®°', }, { icon: '/static/images/icon/fukuanliushui@2x.png', label: '仿¬¾æµæ°´', }, { icon: '/static/images/icon/gongyingshangwanglai@2x.png', label: 'ä¾åºå徿¥', }, ]); // åååå ¬åè½æ°æ® const collaborationItems = reactive([{ icon: '/static/images/icon/gongchuguanli@2x.png', label: 'å ¬åºç®¡ç', }, { icon: '/static/images/icon/qingjiaguanli@2x.png', label: '请å管ç', }, { icon: '/static/images/icon/chuchaiguanli@2x.png', label: 'åºå·®ç®¡ç', }, { icon: '/static/images/icon/xietongshenpi@2x.png', label: 'åå审æ¹', }, { icon: '/static/images/icon/kehubaifang@2x.png', label: 'å®¢æ·æè®¿', }, { icon: '/static/images/icon/qingjiaguanli@2x.png', label: 'éç¥å ¬å', }, ]); // åååå ¬åè½æ°æ®inventoryManagement/receiptManagement const inventoryManagement = reactive([{ icon: '/static/images/icon/rukuguanli@2x.png', label: 'èªå®ä¹å ¥åº', }, { icon: '/static/images/icon/zidingyichuku.png', label: 'èªå®ä¹åºåº', }, ]); // ç产管æ§åè½æ°æ® const productionItems = reactive([{ icon: '/static/images/icon/shengchandingdan@2x.png', label: 'ç产订å', bgColor: '#FF9800' }, { icon: '/static/images/icon/shengchanpaigong@2x.png', label: 'ç产派工', bgColor: '#FF6B35' }, { icon: '/static/images/icon/shengchanpaichan@2x.png', label: 'å·¥åºæäº§', bgColor: '#E91E63' }, { icon: '/static/images/icon/shengchanbaogong@2x.png', label: 'ç产æ¥å·¥', bgColor: '#673AB7' }, { icon: '/static/images/icon/shengchanhesuan@2x.png', label: 'çäº§æ ¸ç®', bgColor: '#3F51B5' } ]); // 设å¤ç®¡çåè½æ°æ® const equipmentItems = reactive([{ icon: '/static/images/icon/shebeitaizhang@2x.png', label: '设å¤å°è´¦', }, { icon: '/static/images/icon/shbeibaoxiu@2x.png', label: 'è®¾å¤æ¥ä¿®', }, { icon: '/static/images/icon/shbeibaoyang@2x.png', label: '设å¤ä¿å »', }, { icon: '/static/images/icon/xunjianshangchuan@2x.png', label: 'å·¡æ£ä¸ä¼ ', }, // { // icon: '/static/images/icon/guzhangfenxi@2x.png', // label: 'åæè¿½æº¯', // bgColor: '#ff9800' // }, // { // icon: '/static/images/icon/zhinengpaidan@2x.png', // label: 'æºè½æ´¾å', // bgColor: '#ff6b35' // }, // { // icon: '/static/images/icon/zuoyezhidao@2x.png', // label: 'ä½ä¸æå¯¼', // bgColor: '#4caf50' // }, // { // icon: '/static/images/icon/jieguoyanzheng@2x.png', // label: 'ç»æéªè¯', // bgColor: '#9c27b0' // } ]); // å¤ç常ç¨åè½ç¹å» const handleCommonItemClick = (item) => { // æ ¹æ®ä¸åçåè½é¡¹è¿è¡è·³è½¬ switch (item.label) { case 'éå®å°è´¦': uni.navigateTo({ url: '/pages/sales/salesAccount/index' }); break; case 'å¼ç¥¨ç»è®°': uni.navigateTo({ url: '/pages/sales/invoicingRegistration/index' }); break; case 'å¼ç¥¨å°è´¦': uni.navigateTo({ url: '/pages/sales/invoiceLedger/index' }); break; case '忬¾ç»è®°': uni.navigateTo({ url: '/pages/sales/receiptPayment/index' }); break; case '忬¾æµæ°´': uni.navigateTo({ url: '/pages/sales/receiptPaymentHistory/index' }); break; case '客æ·å¾æ¥': uni.navigateTo({ url: '/pages/sales/receiptPaymentLedger/index' }); break; case 'éè´å°è´¦': uni.navigateTo({ url: '/pages/procurementManagement/procurementLedger/index' }); break; case 'æ¥ç¥¨ç»è®°': uni.navigateTo({ url: '/pages/procurementManagement/invoiceEntry/index' }); break; case 'æ¥ç¥¨å°è´¦': uni.navigateTo({ url: '/pages/procurementManagement/procurementInvoiceLedger/index' }); break; case '仿¬¾ç»è®°': uni.navigateTo({ url: '/pages/procurementManagement/paymentEntry/index' }); break; case '仿¬¾æµæ°´': uni.navigateTo({ url: '/pages/procurementManagement/receiptPaymentHistory/index' }); break; case 'ä¾åºå徿¥': uni.navigateTo({ url: '/pages/procurementManagement/paymentLedger/index' }); break; case 'å ¬åºç®¡ç': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index1' }); break; case '请å管ç': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index2' }); break; case 'åºå·®ç®¡ç': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index3' }); break; case 'åå审æ¹': uni.navigateTo({ url: '/pages/cooperativeOffice/collaborativeApproval/index' }); break; case 'å®¢æ·æè®¿': uni.navigateTo({ url: '/pages/cooperativeOffice/clientVisit/index' }); break; case 'éç¥å ¬å': uni.navigateTo({ url: '/pages/cooperativeOffice/noticeManagement/index' }); break; case 'èªå®ä¹å ¥åº': uni.navigateTo({ url: '/pages/inventoryManagement/receiptManagement/index' }); break; case 'èªå®ä¹åºåº': uni.navigateTo({ url: '/pages/inventoryManagement/issueManagement/index' }); break; case 'ç产订å': uni.navigateTo({ url: '/pages/productionManagement/productionOrder/index' }); break; case 'ç产派工': uni.navigateTo({ url: '/pages/productionManagement/productionDispatching/index' }); break; case 'å·¥åºæäº§': uni.navigateTo({ url: '/pages/productionManagement/operationScheduling/index' }); break; case 'ç产æ¥å·¥': uni.navigateTo({ url: '/pages/productionManagement/productionReporting/index' }); break; case 'çäº§æ ¸ç®': uni.navigateTo({ url: '/pages/productionManagement/productionCosting/index' }); break; case '设å¤å°è´¦': uni.navigateTo({ url: '/pages/equipmentManagement/ledger/index' }); break; case 'è®¾å¤æ¥ä¿®': uni.navigateTo({ url: '/pages/equipmentManagement/repair/index' }); break; case '设å¤ä¿å »': uni.navigateTo({ url: '/pages/equipmentManagement/upkeep/index' }); break; case 'å·¡æ£ä¸ä¼ ': uni.navigateTo({ url: '/pages/inspectionUpload/index' }); break; case 'åæè¿½æº¯': uni.navigateTo({ url: '/pages/equipmentManagement/faultAnalysis/index' }); break; case 'æºè½æ´¾å': uni.navigateTo({ url: '/pages/equipmentManagement/smartDispatch/index' }); break; case 'ä½ä¸æå¯¼': uni.navigateTo({ url: '/pages/equipmentManagement/sop/index' }); break; case 'ç»æéªè¯': uni.navigateTo({ url: '/pages/equipmentManagement/verification/index' }); break; default: uni.showToast({ title: `ç¹å»äº${item.label}`, icon: 'none' }); } }; // å建对åç»ä»¶çå¼ç¨ const uToastRef = ref(null); function getUserLoginFacotryList() { userLoginFacotryList({ userName: userStore.nickName }).then(res => { // æ£æ¥res.dataæ¯å¦ä¸ºæ°ç» factoryList.value[0] = [] if (res.data && Array.isArray(res.data)) { factoryListTem.value = res.data res.data.forEach(item => { factoryList.value[0].push(item.deptName) }) factoryId.value = userStore.currentDeptId } else { // 妿res.data䏿¯æ°ç»ï¼è®¾ç½®ä¸ºç©ºæ°ç» factoryList.value = [] } }).catch(error => { modal.msgError('è·åå ¬å¸å表失败:', error) factoryList.value = [] }) } modal.loading("å·æ°ä¸ï¼è¯·èå¿çå¾ ...") userStore.loginCheckFactory(loginForm).then(() => { modal.closeLoading() nextTick(() => { loginSuccess() const changeFactory = async (arr) => { show.value = false; const factoryId = factoryListTem.value[arr.indexs[0]].deptId const loginForm = { username: userStore.name, password: uni.getStorageSync('remembered_password'), factoryId: factoryId, } modal.loading("å·æ°ä¸ï¼è¯·èå¿çå¾ ...") userStore.loginCheckFactory(loginForm).then(() => { modal.closeLoading() nextTick(() => { loginSuccess() }); }).catch(() => { modal.closeLoading() }) } function loginSuccess(result) { uni.reLaunch({ url: '/pages/index' }); }).catch(() => { modal.closeLoading() }) } function loginSuccess(result) { uni.reLaunch({ url: '/pages/index' }); } // å®ä¹æ¹æ³ const click = (name) => { if (uToastRef.value) { uToastRef.value.success(`ç¹å»äºç¬¬${name + 1}个`); // 注æï¼è¿éå 1æ¯å 为é常æä»¬æ¯ä»ç¬¬1个å¼å§è®¡æ°ç } }; onMounted(() => { // è®¾ç½®ç¨æ·ä¿¡æ¯ userStore.getInfo() getUserLoginFacotryList() // å¯å¨éç¥ç¶æå®æ¶å¨ startStatusTimer() }); // å®ä¹æ¹æ³ const click = (name) => { if (uToastRef.value) { uToastRef.value.success(`ç¹å»äºç¬¬${name + 1}个`); // 注æï¼è¿éå 1æ¯å 为é常æä»¬æ¯ä»ç¬¬1个å¼å§è®¡æ°ç } }; const isShowNoticesList = ref(true) // è·åå ¬åæ°é const getNoticesList = () => { if(!isShowNoticesList.value){ return } const current_date = dayjs().format('YYYY-MM-DD') noticesList({ current:-1, size:-1, status: 1, current_date }).then(resp => { console.log('noticesList',resp) if (resp.code != 200 || !resp.data||!resp.data.records||!resp.data.records.length) { return } const res = uni.getAppAuthorizeSetting(); if (res.notificationAuthorized == 'denied') { uni.showModal({ title: 'æç¤º', content: '请å¨è®¾ç½®ä¸å¼å¯éç¥æé', success: (res) => { if (res.confirm) { uni.openAppAuthorizeSetting({ success: (res) => {} }); }else{ isShowNoticesList.value = false } } }); return } resp.data.records.map(item=>{ createPushMessage(item.title) }) }).catch(error => { modal.msgError('è·åå ¬åæ°é:', error) }) } const createPushMessage = (text) => { uni.createPushMessage({ title: 'å ¬åéç¥', content: text||'', success: (resp) => { console.log('success', resp) isShowNoticesList.value = false }, fail: (resp) => { console.log('fail', resp) } }) } onMounted(() => { // è®¾ç½®ç¨æ·ä¿¡æ¯ userStore.getInfo() getUserLoginFacotryList() // å¯å¨éç¥ç¶æå®æ¶å¨ startStatusTimer() }); onShow(()=>{ getNoticesList() }) </script> <style scoped lang="scss"> .content { background: linear-gradient(135deg, #f8f9fa 0%, #e3f2fd 100%); min-height: 100vh; padding: 1.25rem; /* 为ææè®¾å¤è®¾ç½®åºç¡padding-top */ padding-top: 40px; position: relative; /* iOS设å¤ä½¿ç¨env()彿°å¤çå®å ¨åºå */ padding-top: env(safe-area-inset-top); /* 为å®å设å¤è®¾ç½®æ´å¤§çé¡¶é¨å è¾¹è· */ /* #ifdef APP-PLUS && !MP && !H5 */ padding-top: 45px; /* #endif */ /* H5åå°ç¨åºå¹³å°çéç¨æ ·å¼ */ /* #ifdef H5 || MP */ padding-top: 30px; /* #endif */ &::before { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(41, 121, 255, 0.03)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>'); pointer-events: none; z-index: -1; } &::after { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at 20% 80%, rgba(41, 121, 255, 0.02) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(156, 39, 176, 0.02) 0%, transparent 50%); pointer-events: none; z-index: -1; } } .content { background: linear-gradient(135deg, #f8f9fa 0%, #e3f2fd 100%); min-height: 100vh; padding: 1.25rem; /* 为ææè®¾å¤è®¾ç½®åºç¡padding-top */ padding-top: 40px; position: relative; .header-section { margin-bottom: 1rem; animation: fadeInDown 0.6s ease-out; /* 为å®å设å¤é¢å¤è°æ´å¤´é¨ä½ç½® */ /* #ifdef APP-PLUS && !MP && !H5 */ margin-top: 10px; /* #endif */ } /* iOS设å¤ä½¿ç¨env()彿°å¤çå®å ¨åºå */ padding-top: env(safe-area-inset-top); .currentFactory { margin-top: 0.5rem; margin-left: 0.25rem; font-weight: 500; display: flex; } /* 为å®å设å¤è®¾ç½®æ´å¤§çé¡¶é¨å è¾¹è· */ /* #ifdef APP-PLUS && !MP && !H5 */ padding-top: 45px; /* #endif */ .factoryName { width: auto; } /* H5åå°ç¨åºå¹³å°çéç¨æ ·å¼ */ /* #ifdef H5 || MP */ padding-top: 30px; /* #endif */ :deep(.u-text) { align-items: center; } &::before { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(41, 121, 255, 0.03)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>'); pointer-events: none; z-index: -1; } .hero-section { margin-bottom: 1rem; animation: fadeInUp 0.6s ease-out 0.1s both; } .bg-img { width: 100%; height: 8.75rem; background-image: url("../static/images/banner/backview.png"); background-size: cover; border-radius: 0.75rem; position: relative; overflow: hidden; box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.15); &::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: conic-gradient(from 0deg, transparent, rgba(255,255,255,0.1), transparent, rgba(255,255,255,0.05), transparent); animation: rotate 20s linear infinite; } &::after { content: ''; position: absolute; top: 0; right: 0; width: 7.5rem; height: 7.5rem; background: radial-gradient(circle, rgba(255,255,255,0.15) 0%, transparent 70%); border-radius: 50%; transform: translate(2.5rem, -2.5rem); } } .hero-content { position: relative; z-index: 1; padding: 1.25rem 1.25rem 1.6rem 1.25rem; height: 100%; display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; } .hero-title { color: #ffffff; font-size: 1.625rem; font-weight: 700; letter-spacing: 0.03125rem; text-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5); } .hero-subtitle { font-size: 0.8125rem; margin-top: 0.375rem; } .hero-wave { height: 2.75rem; } .hero-subtitle { color: rgba(255, 255, 255, 0.9); font-size: 0.8125rem; margin-top: 0.375rem; font-weight: 400; text-shadow: 0 0.0625rem 0.125rem rgba(0, 0, 0, 0.5); } .hero-wave { position: absolute; left: 0; right: 0; bottom: 0; height: 2.75rem; background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'><path fill='%23ffffff' fill-opacity='0.2' d='M0,224L48,218.7C96,213,192,203,288,197.3C384,192,480,192,576,176C672,160,768,128,864,122.7C960,117,1056,139,1152,144C1248,149,1344,139,1392,133.3L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z'></path></svg>") no-repeat bottom center/cover; pointer-events: none; } .notice-section { margin-bottom: 1rem; animation: fadeInUp 0.6s ease-out 0.2s both; } .notice { width: 100%; background: linear-gradient(135deg, #EAF2FF 0%, #BBDEFB 100%); border: 0.0625rem solid #e3f2fd; border-radius: 0.75rem; padding: 1rem; box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.08); position: relative; overflow: hidden; &::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, transparent, rgba(255,255,255,0.6), transparent); animation: shine 4s infinite; } &::after { content: ''; position: absolute; top: 0; right: 0; width: 5rem; height: 5rem; background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, transparent 70%); border-radius: 50%; transform: translate(1.875rem, -1.875rem); } &:hover { transform: translateY(-0.125rem); box-shadow: 0 0.5rem 1.875rem rgba(0, 0, 0, 0.1); } } @keyframes shine { 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); } 100% { transform: translateX(100%) translateY(100%) rotate(45deg); } } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-1.25rem); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(1.25rem); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInScale { 0% { opacity: 0; transform: translateY(0.5rem) scale(0.96); } 100% { opacity: 1; transform: translateY(0) scale(1); } } .notice-content { display: flex; align-items: center; height: 100%; position: relative; z-index: 1; } .notice-left { margin-right: 1rem; } .notice-status { font-weight: 600; font-size: 1rem; color: #1976d2; } .notice-separator { width: 0.0625rem; height: 1.5rem; background: #e0e0e0; margin-right: 1rem; } .notice-right { display: flex; align-items: center; justify-content: space-between; flex: 1; } .notice-label { color: #333; font-size: 0.875rem; font-weight: 500; margin-right: 0.75rem; } .notice-text { font-weight: 400; font-size: 0.875rem; color: #666666; } .notice-number { font-weight: 600; font-size: 1rem; color: #1976d2; margin-left: 0.25rem; } .notice-unit { color: #666666; font-size: 0.875rem; margin-left: 0.125rem; } /* åè½æ¨¡åæ ·å¼ */ .common-module { margin-bottom: 1.5rem; background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); border-radius: 1rem; padding: 1rem; box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06); border: none; position: relative; overflow: hidden; transition: all 0.3s ease; &::after { content: ''; position: absolute; top: 0; right: 0; width: 3.75rem; height: 3.75rem; background: radial-gradient(circle, rgba(0,0,0,0.02) 0%, transparent 70%); border-radius: 50%; transform: translate(1.875rem, -1.875rem); } } .marketing-module { --module-color: #2979ff; } .purchase-module { --module-color: #1976d2; } .collaboration-module { --module-color: #4caf50; } .production-module { --module-color: #FF9800; } .equipment-module { --module-color: #9c27b0; } .module-header { margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: space-between; } .module-title-container { display: flex; align-items: center; } .module-title { color: #333333; font-size: 1.125rem; font-weight: 600; position: relative; } .module-subtitle { color: #666666; font-size: 0.75rem; font-weight: 400; margin-left: 0.5rem; } .module-content { width: 100%; display: grid; gap: 1rem; } .icon-container { width: 3.25rem; height: 3.25rem; border-radius: 0.75rem; display: flex; align-items: center; justify-content: center; margin-bottom: 0.375rem; box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12); transition: all 0.2s ease; position: relative; overflow: hidden; animation: fadeInScale 0.5s ease both; &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, transparent 50%, rgba(255,255,255,0.05) 100%); opacity: 0; transition: opacity 0.3s ease; } &::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 0.75rem; background: linear-gradient(45deg, transparent, rgba(255,255,255,0.2), transparent); opacity: 0; transition: opacity 0.3s ease; } &:hover { transform: translateY(-0.1875rem) scale(1.02); box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18); &::before, &::after { opacity: 1; content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at 20% 80%, rgba(41, 121, 255, 0.02) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(156, 39, 176, 0.02) 0%, transparent 50%); pointer-events: none; z-index: -1; } } &:active { transform: scale(0.97); box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18); } } .item-label { font-size: 0.8125rem; color: #555555; text-align: center; display: block; line-height: 1.4; font-weight: 500; margin-top: 0.25rem; margin-bottom: 0.625rem; } .header-section { margin-bottom: 1rem; animation: fadeInDown 0.6s ease-out; /* 为å®å设å¤é¢å¤è°æ´å¤´é¨ä½ç½® */ /* #ifdef APP-PLUS && !MP && !H5 */ margin-top: 10px; /* #endif */ } .grid-text { font-size: 0.875rem; color: #909399; padding: 0.625rem 0 1.25rem 0; /* #ifndef APP-PLUS */ box-sizing: border-box; /* #endif */ } .currentFactory { margin-top: 0.5rem; margin-left: 0.25rem; font-weight: 500; display: flex; } /* æè²æ¨¡å¼éé */ @media (prefers-color-scheme: dark) { .content { background: linear-gradient(135deg, #121317 0%, #161a20 100%); .factoryName { width: auto; } .content::before { background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(255, 255, 255, 0.05)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>'); :deep(.u-text) { align-items: center; } .common-module { background: linear-gradient(135deg, #1e1f24 0%, #23252b 100%); box-shadow: 0 0.375rem 1.5rem rgba(0,0,0,0.35); .hero-section { margin-bottom: 1rem; animation: fadeInUp 0.6s ease-out 0.1s both; } .module-title { color: #e9edf3; } .module-subtitle, .item-label, .notice-text, .notice-unit, .notice-label { color: #c7cbd3; } .notice { background: linear-gradient(135deg, #1b2330 0%, #1a2432 100%); border-color: rgba(255,255,255,0.06); box-shadow: 0 0.375rem 1.25rem rgba(0,0,0,0.4); } .notice-status, .notice-number { color: #8ab4ff; } .bg-img { background: linear-gradient(135deg, #1f4fb9 0%, #0e3a8a 100%); width: 100%; height: 8.75rem; background-image: url("../static/images/banner/backview.png"); background-size: cover; border-radius: 0.75rem; position: relative; overflow: hidden; box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.15); &::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: conic-gradient(from 0deg, transparent, rgba(255, 255, 255, 0.1), transparent, rgba(255, 255, 255, 0.05), transparent); animation: rotate 20s linear infinite; } &::after { content: ''; position: absolute; top: 0; right: 0; width: 7.5rem; height: 7.5rem; background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%); border-radius: 50%; transform: translate(2.5rem, -2.5rem); } } } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .hero-content { position: relative; z-index: 1; padding: 1.25rem 1.25rem 1.6rem 1.25rem; height: 100%; display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-1.25rem); } to { opacity: 1; transform: translateY(0); } } .hero-title { color: #ffffff; font-size: 1.625rem; font-weight: 700; letter-spacing: 0.03125rem; text-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5); } @keyframes fadeInUp { from { opacity: 0; transform: translateY(1.25rem); } to { opacity: 1; transform: translateY(0); } } .hero-subtitle { font-size: 0.8125rem; margin-top: 0.375rem; } @keyframes fadeInScale { 0% { opacity: 0; transform: translateY(0.5rem) scale(0.96); } 100% { opacity: 1; transform: translateY(0) scale(1); } } .hero-wave { height: 2.75rem; } .notice-left { margin-right: 1rem; } .notice-status { font-size: 1rem; } .notice-separator { width: 0.0625rem; height: 1.5rem; margin-right: 1rem; } .notice-label { font-size: 0.875rem; margin-right: 0.75rem; } .notice-text { font-size: 0.875rem; } .notice-number { font-size: 1rem; margin-left: 0.25rem; } .notice-unit { font-size: 0.875rem; margin-left: 0.125rem; } .hero-subtitle { color: rgba(255, 255, 255, 0.9); font-size: 0.8125rem; margin-top: 0.375rem; font-weight: 400; text-shadow: 0 0.0625rem 0.125rem rgba(0, 0, 0, 0.5); } .common-module { margin-bottom: 1.5rem; background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); border-radius: 1rem; padding: 1rem; box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06); border: none; position: relative; overflow: hidden; transition: all 0.3s ease; &::after { content: ''; .hero-wave { position: absolute; top: 0; left: 0; right: 0; width: 3.75rem; height: 3.75rem; background: radial-gradient(circle, rgba(0,0,0,0.02) 0%, transparent 70%); border-radius: 50%; transform: translate(1.875rem, -1.875rem); bottom: 0; height: 2.75rem; background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 320' preserveAspectRatio='none'><path fill='%23ffffff' fill-opacity='0.2' d='M0,224L48,218.7C96,213,192,203,288,197.3C384,192,480,192,576,176C672,160,768,128,864,122.7C960,117,1056,139,1152,144C1248,149,1344,139,1392,133.3L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z'></path></svg>") no-repeat bottom center/cover; pointer-events: none; } } .marketing-module { --module-color: #2979ff; } .purchase-module { --module-color: #1976d2; } .collaboration-module { --module-color: #4caf50; } .production-module { --module-color: #FF9800; } .equipment-module { --module-color: #9c27b0; } .module-header { margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: space-between; } .module-title-container { display: flex; align-items: center; } .module-title { color: #333333; font-size: 1.125rem; font-weight: 600; position: relative; } .module-subtitle { color: #666666; font-size: 0.75rem; font-weight: 400; margin-left: 0.5rem; } .module-content { width: 100%; display: grid; gap: 1rem; } .icon-container { width: 3.25rem; height: 3.25rem; border-radius: 0.75rem; display: flex; align-items: center; justify-content: center; margin-bottom: 0.375rem; box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12); transition: all 0.2s ease; position: relative; overflow: hidden; animation: fadeInScale 0.5s ease both; &:hover { transform: translateY(-0.1875rem) scale(1.02); box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18); .notice-section { margin-bottom: 1rem; animation: fadeInUp 0.6s ease-out 0.2s both; } &:active { transform: scale(0.97); box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18); .notice { width: 100%; background: linear-gradient(135deg, #EAF2FF 0%, #BBDEFB 100%); border: 0.0625rem solid #e3f2fd; border-radius: 0.75rem; padding: 1rem; box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.08); position: relative; overflow: hidden; &::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.6), transparent); animation: shine 4s infinite; } &::after { content: ''; position: absolute; top: 0; right: 0; width: 5rem; height: 5rem; background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, transparent 70%); border-radius: 50%; transform: translate(1.875rem, -1.875rem); } &:hover { transform: translateY(-0.125rem); box-shadow: 0 0.5rem 1.875rem rgba(0, 0, 0, 0.1); } } } .item-label { font-size: 0.8125rem; margin-top: 0.25rem; margin-bottom: 0.625rem; } .grid-text { font-size: 0.875rem; } @media (prefers-color-scheme: dark) { .common-module { box-shadow: 0 0.375rem 1.5rem rgba(0,0,0,0.35); } .notice { box-shadow: 0 0.375rem 1.25rem rgba(0,0,0,0.4); } } </style> @keyframes shine { 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); } 100% { transform: translateX(100%) translateY(100%) rotate(45deg); } } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-1.25rem); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(1.25rem); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInScale { 0% { opacity: 0; transform: translateY(0.5rem) scale(0.96); } 100% { opacity: 1; transform: translateY(0) scale(1); } } .notice-content { display: flex; align-items: center; height: 100%; position: relative; z-index: 1; } .notice-left { margin-right: 1rem; } .notice-status { font-weight: 600; font-size: 1rem; color: #1976d2; } .notice-separator { width: 0.0625rem; height: 1.5rem; background: #e0e0e0; margin-right: 1rem; } .notice-right { display: flex; align-items: center; justify-content: space-between; flex: 1; } .notice-label { color: #333; font-size: 0.875rem; font-weight: 500; margin-right: 0.75rem; } .notice-text { font-weight: 400; font-size: 0.875rem; color: #666666; } .notice-number { font-weight: 600; font-size: 1rem; color: #1976d2; margin-left: 0.25rem; } .notice-unit { color: #666666; font-size: 0.875rem; margin-left: 0.125rem; } /* åè½æ¨¡åæ ·å¼ */ .common-module { margin-bottom: 1.5rem; background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); border-radius: 1rem; padding: 1rem; box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06); border: none; position: relative; overflow: hidden; transition: all 0.3s ease; &::after { content: ''; position: absolute; top: 0; right: 0; width: 3.75rem; height: 3.75rem; background: radial-gradient(circle, rgba(0, 0, 0, 0.02) 0%, transparent 70%); border-radius: 50%; transform: translate(1.875rem, -1.875rem); } } .marketing-module { --module-color: #2979ff; } .purchase-module { --module-color: #1976d2; } .collaboration-module { --module-color: #4caf50; } .production-module { --module-color: #FF9800; } .equipment-module { --module-color: #9c27b0; } .module-header { margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: space-between; } .module-title-container { display: flex; align-items: center; } .module-title { color: #333333; font-size: 1.125rem; font-weight: 600; position: relative; } .module-subtitle { color: #666666; font-size: 0.75rem; font-weight: 400; margin-left: 0.5rem; } .module-content { width: 100%; display: grid; gap: 1rem; } .icon-container { width: 3.25rem; height: 3.25rem; border-radius: 0.75rem; display: flex; align-items: center; justify-content: center; margin-bottom: 0.375rem; box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12); transition: all 0.2s ease; position: relative; overflow: hidden; animation: fadeInScale 0.5s ease both; &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.05) 100%); opacity: 0; transition: opacity 0.3s ease; } &::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 0.75rem; background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.2), transparent); opacity: 0; transition: opacity 0.3s ease; } &:hover { transform: translateY(-0.1875rem) scale(1.02); box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18); &::before, &::after { opacity: 1; } } &:active { transform: scale(0.97); box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18); } } .item-label { font-size: 0.8125rem; color: #555555; text-align: center; display: block; line-height: 1.4; font-weight: 500; margin-top: 0.25rem; margin-bottom: 0.625rem; } .grid-text { font-size: 0.875rem; color: #909399; padding: 0.625rem 0 1.25rem 0; /* #ifndef APP-PLUS */ box-sizing: border-box; /* #endif */ } /* æè²æ¨¡å¼éé */ @media (prefers-color-scheme: dark) { .content { background: linear-gradient(135deg, #121317 0%, #161a20 100%); } .content::before { background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(255, 255, 255, 0.05)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>'); } .common-module { background: linear-gradient(135deg, #1e1f24 0%, #23252b 100%); box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.35); } .module-title { color: #e9edf3; } .module-subtitle, .item-label, .notice-text, .notice-unit, .notice-label { color: #c7cbd3; } .notice { background: linear-gradient(135deg, #1b2330 0%, #1a2432 100%); border-color: rgba(255, 255, 255, 0.06); box-shadow: 0 0.375rem 1.25rem rgba(0, 0, 0, 0.4); } .notice-status, .notice-number { color: #8ab4ff; } .bg-img { background: linear-gradient(135deg, #1f4fb9 0%, #0e3a8a 100%); } } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-1.25rem); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(1.25rem); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInScale { 0% { opacity: 0; transform: translateY(0.5rem) scale(0.96); } 100% { opacity: 1; transform: translateY(0) scale(1); } } .notice-left { margin-right: 1rem; } .notice-status { font-size: 1rem; } .notice-separator { width: 0.0625rem; height: 1.5rem; margin-right: 1rem; } .notice-label { font-size: 0.875rem; margin-right: 0.75rem; } .notice-text { font-size: 0.875rem; } .notice-number { font-size: 1rem; margin-left: 0.25rem; } .notice-unit { font-size: 0.875rem; margin-left: 0.125rem; } .common-module { margin-bottom: 1.5rem; background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); border-radius: 1rem; padding: 1rem; box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06); border: none; position: relative; overflow: hidden; transition: all 0.3s ease; &::after { content: ''; position: absolute; top: 0; right: 0; width: 3.75rem; height: 3.75rem; background: radial-gradient(circle, rgba(0, 0, 0, 0.02) 0%, transparent 70%); border-radius: 50%; transform: translate(1.875rem, -1.875rem); } } .marketing-module { --module-color: #2979ff; } .purchase-module { --module-color: #1976d2; } .collaboration-module { --module-color: #4caf50; } .production-module { --module-color: #FF9800; } .equipment-module { --module-color: #9c27b0; } .module-header { margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: space-between; } .module-title-container { display: flex; align-items: center; } .module-title { color: #333333; font-size: 1.125rem; font-weight: 600; position: relative; } .module-subtitle { color: #666666; font-size: 0.75rem; font-weight: 400; margin-left: 0.5rem; } .module-content { width: 100%; display: grid; gap: 1rem; } .icon-container { width: 3.25rem; height: 3.25rem; border-radius: 0.75rem; display: flex; align-items: center; justify-content: center; margin-bottom: 0.375rem; box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12); transition: all 0.2s ease; position: relative; overflow: hidden; animation: fadeInScale 0.5s ease both; &:hover { transform: translateY(-0.1875rem) scale(1.02); box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18); } &:active { transform: scale(0.97); box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18); } } .item-label { font-size: 0.8125rem; margin-top: 0.25rem; margin-bottom: 0.625rem; } .grid-text { font-size: 0.875rem; } @media (prefers-color-scheme: dark) { .common-module { box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.35); } .notice { box-shadow: 0 0.375rem 1.25rem rgba(0, 0, 0, 0.4); } } </style> src/pages/inspectionUpload/index.vue
@@ -1,46 +1,32 @@ <template> <view class="inspection-upload-page"> <!-- 页é¢å¤´é¨ --> <PageHeader title="å·¡æ£ä¸ä¼ " @back="goBack"/> <PageHeader title="å·¡æ£ä¸ä¼ " @back="goBack" /> <!-- æ°æ®å表 --> <view class="table-section"> <!-- ç产巡æ£å表 --> <view class="task-list"> <view v-for="(item, index) in taskTableData" :key="index" class="task-item" > <view v-for="(item, index) in taskTableData" :key="index" class="task-item"> <view class="task-header"> <view class="task-info"> <text class="task-name">{{ item.taskName }}</text> <text class="task-location">{{ item.inspectionLocation }}</text> </view> <view class="task-actions"> <u-button type="primary" size="small" @click.stop="startScanForTask(item)" :customStyle="{ borderRadius: '15px', height: '30px', fontSize: '12px', marginRight: '8px' }" > <u-button type="primary" size="small" @click.stop="startScanForTask(item)" :customStyle="{ borderRadius: '15px', height: '30px', fontSize: '12px', marginRight: '8px' }"> æ«ç ä¸ä¼ </u-button> <u-button type="success" size="small" @click.stop="viewAttachments(item)" :customStyle="{ borderRadius: '15px', height: '30px', fontSize: '12px' }" > <u-button type="success" size="small" @click.stop="viewAttachments(item)" :customStyle="{ borderRadius: '15px', height: '30px', fontSize: '12px' }"> æ¥çéä»¶ </u-button> </view> @@ -58,64 +44,56 @@ <text class="detail-label">æ§è¡äºº</text> <text class="detail-value">{{ item.inspector }}</text> </view> <view class="detail-item"> <text class="detail-label">ä»»å¡ä¸åæ¥æ</text> <text class="detail-value">{{ item.dateStr }}</text> </view> <view class="detail-item"> <text class="detail-label">ä»»å¡ä¸åæ¥æ</text> <text class="detail-value">{{ item.dateStr }}</text> </view> <view class="detail-item"> <text class="detail-label">å·¡æ£ç¶æ</text> <view class="detail-value"> <uni-tag v-if="item.fileStatus==2" text="已宿" size="small" type="success" inverted></uni-tag> <uni-tag v-else-if="item.fileStatus==1" text="å·¡æ£ä¸" size="small" type="primary" inverted></uni-tag> <uni-tag v-else="" text="æªå·¡æ£" size="small" type="warning" inverted></uni-tag> </view> </view> </view> </view> <uni-load-more :status="loadMoreStatus"></uni-load-more> </view> <!-- ç©ºç¶æ --> <view v-if="taskTableData.length === 0" class="no-data"> <view v-if="taskTableData?.length === 0" class="no-data"> <text>ææ æ°æ®</text> </view> </view> <!-- æ«ç åºå - å ¨å±å¼¹çª --> <view v-if="isScanning" class="qr-scan-overlay"> <view class="qr-scan-container"> <view class="scan-header"> <text class="scan-title">æ«æäºç»´ç </text> <u-button type="error" size="small" @click.stop="stopScan" :customStyle="{ borderRadius: '15px', height: '30px', fontSize: '12px' }" > <u-button type="error" size="small" @click.stop="stopScan" :customStyle="{ borderRadius: '15px', height: '30px', fontSize: '12px' }"> å ³é </u-button> </view> <camera class="qr-camera" device-position="back" flash="off" @scancode="handleScanCode" @error="handleCameraError" ></camera> <camera class="qr-camera" device-position="back" flash="off" @scancode="handleScanCode" @error="handleCameraError"></camera> <view class="scan-frame-wrapper"> <view class="scan-frame"></view> <view class="scan-tip">请å°äºç»´ç æ¾å ¥æ¡å </view> </view> <u-alert v-if="cameraError" :title="cameraError" type="error" :showIcon="true" :closable="true" @close="cameraError = ''" :customStyle="{ <u-alert v-if="cameraError" :title="cameraError" type="error" :showIcon="true" :closable="true" @close="cameraError = ''" :customStyle="{ margin: '10px 0' }" ></u-alert> }"></u-alert> </view> </view> <!-- å¾çä¸ä¼ å¼¹çª - åçå®ç° --> <view v-if="showUploadDialog" class="custom-modal-overlay" @click="closeUploadDialog"> <view class="custom-modal-container" @click.stop> @@ -123,145 +101,109 @@ <view class="upload-popup-header"> <text class="upload-popup-title">ä¸ä¼ å·¡æ£è®°å½</text> </view> <view class="upload-popup-body"> <!-- åç±»æ ç¾é¡µ --> <view class="upload-tabs"> <view class="tab-item" :class="{ active: currentUploadType === 'before' }" @click="switchUploadType('before')" > ç产å </view> <view class="tab-item" :class="{ active: currentUploadType === 'after' }" @click="switchUploadType('after')" > çäº§ä¸ </view> <view class="tab-item" :class="{ active: currentUploadType === 'issue' }" @click="switchUploadType('issue')" > ç产å </view> <view class="upload-popup-body"> <!-- åç±»æ ç¾é¡µ --> <view class="upload-tabs"> <view class="tab-item" :class="{ active: currentUploadType === 'before' }" @click="switchUploadType('before')"> ç产å </view> <!-- å¼å¸¸ç¶æéæ© --> <view class="exception-section"> <text class="section-title">æ¯å¦åå¨å¼å¸¸ï¼</text> <view class="exception-options"> <view class="exception-option" :class="{ active: hasException === false }" @click="setExceptionStatus(false)" > <u-icon name="checkmark-circle" size="20" color="#52c41a"></u-icon> <text>æ£å¸¸</text> </view> <view class="exception-option" :class="{ active: hasException === true }" @click="setExceptionStatus(true)" > <u-icon name="close-circle" size="20" color="#ff4d4f"></u-icon> <text>åå¨å¼å¸¸</text> </view> </view> <view class="tab-item" :class="{ active: currentUploadType === 'after' }" @click="switchUploadType('after')"> çäº§ä¸ </view> <!-- å½ååç±»çä¸ä¼ åºå --> <view class="simple-upload-area"> <view class="upload-buttons"> <u-button type="primary" @click="chooseMedia('image')" :loading="uploading" :disabled="getCurrentFiles().length >= uploadConfig.limit" :customStyle="{ marginRight: '10px', flex: 1 }" > <u-icon name="camera" size="18" color="#fff" style="margin-right: 5px;"></u-icon> {{ uploading ? 'ä¸ä¼ ä¸...' : 'æç §' }} </u-button> <u-button type="success" @click="chooseMedia('video')" :loading="uploading" :disabled="getCurrentFiles().length >= uploadConfig.limit" :customStyle="{ flex: 1 }" > <uni-icons type="videocam" name="videocam" size="18" color="#fff" style="margin-right: 5px;"></uni-icons> {{ uploading ? 'ä¸ä¼ ä¸...' : 'æè§é¢' }} </u-button> <view class="tab-item" :class="{ active: currentUploadType === 'issue' }" @click="switchUploadType('issue')"> ç产å </view> </view> <!-- å¼å¸¸ç¶æéæ© --> <view class="exception-section"> <text class="section-title">æ¯å¦åå¨å¼å¸¸ï¼</text> <view class="exception-options"> <view class="exception-option" :class="{ active: hasException === false }" @click="setExceptionStatus(false)"> <u-icon name="checkmark-circle" size="20" color="#52c41a"></u-icon> <text>æ£å¸¸</text> </view> <!-- ä¸ä¼ è¿åº¦ --> <view v-if="uploading" class="upload-progress"> <u-line-progress :percentage="uploadProgress" :showText="true" activeColor="#409eff" ></u-line-progress> </view> <!-- å½ååç±»çæä»¶å表 --> <view v-if="getCurrentFiles().length > 0" class="file-list"> <view v-for="(file, index) in getCurrentFiles()" :key="index" class="file-item" > <view class="file-preview-container"> <image v-if="file?.path?.fileType === 'image'" :src="file?.url || file?.tempFilePath?.tempFilePath || file?.path?.tempFilePath" class="file-preview" mode="aspectFill" /> <view v-else class="video-preview"> <uni-icons type="videocam" name="videocam" size="18" color="#fff" style="margin-right: 5px;"></uni-icons> <text class="video-text">è§é¢</text> </view> <!-- å é¤æé® --> <view class="delete-btn" @click="removeFile(index)"> <u-icon name="close" size="12" color="#fff"></u-icon> </view> </view> <view class="file-info"> <text class="file-name">{{ file.bucketFilename || file.name || (file.type === 'image' ? 'å¾ç' : 'è§é¢') }}</text> <text class="file-size">{{ formatFileSize(file.size) }}</text> </view> </view> </view> <view v-if="getCurrentFiles().length === 0" class="empty-state"> <text>è¯·éæ©è¦ä¸ä¼ ç{{ getUploadTypeText() }}å¾çæè§é¢</text> </view> <!-- ç»è®¡ä¿¡æ¯ --> <view class="upload-summary"> <text class="summary-text"> ç产å: {{ beforeModelValue.length }}个æä»¶ | ç产ä¸: {{ afterModelValue.length }}个æä»¶ | ç产å: {{ issueModelValue.length }}个æä»¶ </text> <view class="exception-option" :class="{ active: hasException === true }" @click="setExceptionStatus(true)"> <u-icon name="close-circle" size="20" color="#ff4d4f"></u-icon> <text>åå¨å¼å¸¸</text> </view> </view> </view> <!-- å½ååç±»çä¸ä¼ åºå --> <view class="simple-upload-area"> <view class="upload-buttons"> <u-button type="primary" @click="chooseMedia('image')" :loading="uploading" :disabled="getCurrentFiles().length >= uploadConfig.limit" :customStyle="{ marginRight: '10px', flex: 1 }"> <u-icon name="camera" size="18" color="#fff" style="margin-right: 5px;"></u-icon> {{ uploading ? 'ä¸ä¼ ä¸...' : 'æç §' }} </u-button> <u-button type="success" @click="chooseMedia('video')" :loading="uploading" :disabled="getCurrentFiles().length >= uploadConfig.limit" :customStyle="{ flex: 1 }"> <uni-icons type="videocam" name="videocam" size="18" color="#fff" style="margin-right: 5px;"></uni-icons> {{ uploading ? 'ä¸ä¼ ä¸...' : 'æè§é¢' }} </u-button> </view> <!-- ä¸ä¼ è¿åº¦ --> <view v-if="uploading" class="upload-progress"> <u-line-progress :percentage="uploadProgress" :showText="true" activeColor="#409eff"></u-line-progress> </view> <!-- å½ååç±»çæä»¶å表 --> <view v-if="getCurrentFiles().length > 0" class="file-list"> <view v-for="(file, index) in getCurrentFiles()" :key="index" class="file-item"> <view class="file-preview-container"> <image v-if="file?.path?.fileType === 'image'" :src="file?.url || file?.tempFilePath?.tempFilePath || file?.path?.tempFilePath" class="file-preview" mode="aspectFill" /> <view v-else class="video-preview"> <uni-icons type="videocam" name="videocam" size="18" color="#fff" style="margin-right: 5px;"></uni-icons> <text class="video-text">è§é¢</text> </view> <!-- å é¤æé® --> <view class="delete-btn" @click="removeFile(index)"> <u-icon name="close" size="12" color="#fff"></u-icon> </view> </view> <view class="file-info"> <text class="file-name">{{ file.bucketFilename || file.name || (file.type === 'image' ? 'å¾ç' : 'è§é¢') }}</text> <text class="file-size">{{ formatFileSize(file.size) }}</text> </view> </view> </view> <view v-if="getCurrentFiles().length === 0" class="empty-state"> <text>è¯·éæ©è¦ä¸ä¼ ç{{ getUploadTypeText() }}å¾çæè§é¢</text> </view> <!-- ç»è®¡ä¿¡æ¯ --> <view class="upload-summary"> <text class="summary-text"> ç产å: {{ beforeModelValue.length }}个æä»¶ | ç产ä¸: {{ afterModelValue.length }}个æä»¶ | ç产å: {{ issueModelValue.length }}个æä»¶ </text> </view> </view> </view> <view class="upload-popup-footer"> <u-button @click="closeUploadDialog" :customStyle="{ marginRight: '10px' }">åæ¶</u-button> <u-button v-if="hasException === true" type="warning" @click="goToRepair" :customStyle="{ marginRight: '10px' }" > <u-button v-if="hasException === true" type="warning" @click="goToRepair" :customStyle="{ marginRight: '10px' }"> æ°å¢æ¥ä¿® </u-button> <u-button type="primary" @click="submitUpload">æäº¤</u-button> @@ -269,7 +211,7 @@ </view> </view> </view> <!-- æ¥çéä»¶å¼¹çª --> <view v-if="showAttachmentDialog" class="custom-modal-overlay" @click="closeAttachmentDialog"> <view class="custom-modal-container" @click.stop> @@ -280,62 +222,44 @@ <u-icon name="close" size="16" color="#666"></u-icon> </view> </view> <view class="attachment-popup-body"> <!-- åç±»æ ç¾é¡µ --> <view class="attachment-tabs"> <view class="tab-item" :class="{ active: currentViewType === 'before' }" @click="switchViewType('before')" > <view class="tab-item" :class="{ active: currentViewType === 'before' }" @click="switchViewType('before')"> ç产å ({{ getAttachmentsByType(0).length }}) </view> <view class="tab-item" :class="{ active: currentViewType === 'after' }" @click="switchViewType('after')" > <view class="tab-item" :class="{ active: currentViewType === 'after' }" @click="switchViewType('after')"> çäº§ä¸ ({{ getAttachmentsByType(1).length }}) </view> <view class="tab-item" :class="{ active: currentViewType === 'issue' }" @click="switchViewType('issue')" > <view class="tab-item" :class="{ active: currentViewType === 'issue' }" @click="switchViewType('issue')"> ç产å ({{ getAttachmentsByType(2).length }}) </view> </view> <!-- å½ååç±»çéä»¶å表 --> <view class="attachment-content"> <view v-if="getCurrentViewAttachments().length > 0" class="attachment-list"> <view v-for="(file, index) in getCurrentViewAttachments()" :key="index" class="attachment-item" @click="previewAttachment(file)" > <view v-for="(file, index) in getCurrentViewAttachments()" :key="index" class="attachment-item" @click="previewAttachment(file)"> <view class="attachment-preview-container"> <image v-if="file.type === 'image' || isImageFile(file)" :src="file.url || file.downloadUrl" class="attachment-preview" mode="aspectFill" /> <image v-if="file.type === 'image' || isImageFile(file)" :src="file.url || file.downloadUrl" class="attachment-preview" mode="aspectFill" /> <view v-else class="attachment-video-preview"> <u-icon name="video" size="24" color="#409eff"></u-icon> <text class="video-text">è§é¢</text> </view> </view> <view class="attachment-info"> <text class="attachment-name">{{ file.originalFilename || file.bucketFilename || file.name || 'éä»¶' }}</text> <text class="attachment-name">{{ file.originalFilename || file.bucketFilename || file.name || 'éä»¶' }}</text> <text class="attachment-size">{{ formatFileSize(file.byteSize || file.size) }}</text> </view> </view> </view> <view v-else class="attachment-empty"> <text>该åç±»ææ éä»¶</text> </view> @@ -344,7 +268,7 @@ </view> </view> </view> <!-- è§é¢é¢è§å¼¹çª --> <view v-if="showVideoDialog" class="video-modal-overlay" @click="closeVideoPreview"> <view class="video-modal-container" @click.stop> @@ -355,14 +279,8 @@ </view> </view> <view class="video-modal-body"> <video v-if="currentVideoFile" :src="currentVideoFile.url || currentVideoFile.downloadUrl" class="video-player" controls autoplay @error="handleVideoError" ></video> <video v-if="currentVideoFile" :src="currentVideoFile.url || currentVideoFile.downloadUrl" class="video-player" controls autoplay @error="handleVideoError"></video> </view> </view> </view> @@ -370,11 +288,11 @@ </template> <script setup> import { onMounted, onUnmounted, ref, nextTick, computed } from 'vue' import { onShow } from '@dcloudio/uni-app' import { onMounted, onUnmounted, ref, nextTick, computed, reactive } from 'vue' import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app' import PageHeader from '@/components/PageHeader.vue' import { getLedgerById } from '@/api/equipmentManagement/ledger.js' import {inspectionTaskList, uploadInspectionTask} from "@/api/inspectionManagement"; import { inspectionTaskList, uploadInspectionTask } from "@/api/inspectionManagement"; import { getToken } from "@/utils/auth"; // ç»ä»¶å¼ç¨å·²ç§»é¤ @@ -439,7 +357,7 @@ // 计ç®ä¸ä¼ URL const uploadFileUrl = computed(() => { let baseUrl = ''; if (process.env.VUE_APP_BASE_API) { baseUrl = process.env.VUE_APP_BASE_API; } else if (process.env.NODE_ENV === 'development') { @@ -447,7 +365,7 @@ } else { baseUrl = 'http://114.132.189.42:9068'; } return baseUrl + uploadConfig.action; }) @@ -464,29 +382,68 @@ const isScanning = ref(false) const cameraError = ref('') const pagesPames = reactive({ size: 10, current:1 }) const loadMoreStatus = computed(()=>{ if(loading.value){ return 'loading' } if(noMore.value){ return 'noMore' } return 'more' }) const totalSize = ref(0) const noMore = computed(()=>{ return taskTableData.value.length>=totalSize.value }) const loading = ref(false) const reloadPage = ()=>{ pagesPames.current = 1 taskTableData.value = [] getList() } const loadPage = ()=>{ if(noMore.value||loading.value)return; pagesPames.current += 1 getList() } // çå½å¨æ onMounted(() => { // å»¶è¿åå§åï¼ç¡®ä¿DOM已渲æ nextTick(() => { getList() }) // nextTick(() => { // getList() // }) }) onReachBottom(() => { loadPage() }) onPullDownRefresh(() => { reloadPage() uni.stopPullDownRefresh() }) onShow(() => { // 页颿¾ç¤ºæ¶å·æ°æ°æ® getList() reloadPage() }) // ç»ä»¶éæ¯æ¶çæ¸ ç onUnmounted(() => { // è®¾ç½®åæ¶æ å¿ï¼é»æ¢åç»ç弿¥æä½ isRequestCancelled = true // 忢æ«ç if (isScanning.value) { isScanning.value = false } // å ³éä¸ä¼ å¼¹çª if (showUploadDialog.value) { showUploadDialog.value = false @@ -498,26 +455,23 @@ uni.navigateBack() } // æ¥è¯¢æ°æ® const handleQuery = () => { getList() } // è·ååè¡¨æ°æ® const getList = () => { // æ¾ç¤ºå è½½æç¤º showLoadingToast('å è½½ä¸...') // showLoadingToast('å è½½ä¸...') // è®¾ç½®åæ¶æ å¿ isRequestCancelled = false inspectionTaskList({}).then(res => { loading.value = true inspectionTaskList({...pagesPames}).then(res => { // æ£æ¥ç»ä»¶æ¯å¦è¿åå¨ä¸è¯·æ±æªè¢«åæ¶ if (!isRequestCancelled) { // å¤çä¸åçæ°æ®ç»æ let records = []; if (res && res.data) { // å°è¯å¤ç§å¯è½çæ°æ®ç»æ totalSize.value = res.data.total if (Array.isArray(res.data.records)) { records = res.data.records; } else if (Array.isArray(res.data.rows)) { @@ -528,9 +482,12 @@ records = res.data.list; } } if (records.length > 0) { taskTableData.value = records; taskTableData.value = [...taskTableData.value,...records.map((record)=>{ record.fileStatus = getFileStatus(record) return record })]; } else { taskTableData.value = []; uni.showToast({ @@ -539,8 +496,9 @@ }); } } loading.value =false // å ³éå è½½æç¤º closeToast() // closeToast() }).catch(err => { // æ£æ¥ç»ä»¶æ¯å¦è¿åå¨ä¸è¯·æ±æªè¢«åæ¶ if (!isRequestCancelled) { @@ -551,9 +509,23 @@ icon: 'error' }) } loading.value =false // å ³éå è½½æç¤º closeToast() // closeToast() }) } const getFileStatus = (record)=>{ let _beforeProduction = record.beforeProduction&&record.beforeProduction.length let _afterProduction = record.afterProduction&&record.afterProduction.length let _productionIssues = record.productionIssues&&record.productionIssues.length if(_beforeProduction&&_afterProduction&&_productionIssues){ return 2 }else if(_beforeProduction||_afterProduction||_productionIssues){ return 1 }else{ return 0 } } // 为æå®ä»»å¡å¼å§æ«ç @@ -561,10 +533,10 @@ try { // è®°å½å½åæ«æçä»»å¡ currentScanningTask.value = task // æ¾ç¤ºæ«æçé¢ isScanning.value = true // 使ç¨uniappçæ«ç API uni.scanCode({ success: (res) => { @@ -599,7 +571,7 @@ try { // è§£æäºç»´ç æ°æ®ï¼æådeviceId let deviceId = '' // æ£æ¥æ¯å¦æ¯URLæ ¼å¼ if (result.result.includes('deviceId=')) { // ä»URL䏿ådeviceId @@ -618,7 +590,7 @@ deviceId = result.result } } if (!deviceId) { uni.showToast({ title: 'æªè¯å«å°è®¾å¤ID', @@ -627,20 +599,20 @@ isScanning.value = false return } // è·åå½åä»»å¡çtaskId const currentTaskId = currentScanningTask.value?.taskId || currentScanningTask.value?.id // 对æ¯deviceIdåtaskId if (deviceId === currentTaskId.toString()) { uni.showToast({ title: 'è¯å«æå', icon: 'success' }) // å å ³éæ«æçé¢ isScanning.value = false // å»¶è¿æå¼ä¸ä¼ å¼¹çªï¼ç¡®ä¿æ«æçé¢å®å ¨å ³é setTimeout(() => { openUploadDialog(currentScanningTask.value) @@ -650,11 +622,11 @@ title: 'è¯·æ«ææ£ç¡®ç设å¤', icon: 'error' }) // å ³éæ«æçé¢ isScanning.value = false } } catch (error) { uni.showToast({ title: error.message || 'æ°æ®è§£æå¤±è´¥', @@ -675,13 +647,13 @@ storageBlobDTO: [] // åå§åæä»¶å表 }; } // 设置ä¸ä¼ ç¶æç±»åï¼å¯ä»¥æ ¹æ®ä»»å¡ç±»å设置ä¸åçç¶æï¼ uploadStatusType.value = 0 // é»è®¤ç¶æ // æ¸ ç©ºä¹åçæä»¶ uploadFiles.value = [] // æ¾ç¤ºä¸ä¼ å¼¹çª showUploadDialog.value = true } @@ -708,11 +680,11 @@ const getCurrentFiles = () => { switch (currentUploadType.value) { case 'before': return beforeModelValue.value return beforeModelValue.value||[] case 'after': return afterModelValue.value return afterModelValue.value||[] case 'issue': return issueModelValue.value return issueModelValue.value||[] default: return [] } @@ -758,17 +730,17 @@ issue: issueModelValue.value } } uni.setStorageSync('repairTaskInfo', JSON.stringify(taskInfo)) // è·³è½¬å°æ°å¢æ¥ä¿®é¡µé¢ uni.navigateTo({ url: '/pages/equipmentManagement/repair/add' }) // å ³éä¸ä¼ å¼¹çª closeUploadDialog() } catch (error) { console.error('跳转æ¥ä¿®é¡µé¢å¤±è´¥:', error) uni.showToast({ @@ -789,7 +761,7 @@ }) return } // æ£æ¥æ¯å¦æä»»ä½æä»¶ä¸ä¼ const totalFiles = beforeModelValue.value.length + afterModelValue.value.length + issueModelValue.value.length; if (totalFiles === 0) { @@ -814,31 +786,31 @@ if (issueModelValue.value.length > 0) { arr.push(...issueModelValue.value); } // æäº¤æ°æ® infoData.value.storageBlobDTO = arr; // æ·»å å¼å¸¸ç¶æä¿¡æ¯ infoData.value.hasException = hasException.value; const result = await uploadInspectionTask({...infoData.value}); const result = await uploadInspectionTask({ ...infoData.value }); // æ£æ¥æäº¤ç»æ if (result && (result.code === 200 || result.success)) { // æäº¤æå closeToast(); // å ³éå è½½æç¤º uni.showToast({ title: 'æäº¤æå', icon: 'success' }) // å ³éå¼¹çª closeUploadDialog() // å·æ°å表 setTimeout(() => { getList() reloadPage() }, 500) } else { // æäº¤å¤±è´¥ closeToast(); @@ -847,11 +819,11 @@ icon: 'error' }) } } catch (error) { console.error('æäº¤ä¸ä¼ 失败:', error) closeToast(); // å ³éå è½½æç¤º let errorMessage = 'æäº¤å¤±è´¥'; if (error.message) { errorMessage = error.message; @@ -860,7 +832,7 @@ } else if (typeof error === 'string') { errorMessage = error; } uni.showToast({ title: errorMessage, icon: 'error' @@ -883,10 +855,10 @@ try { currentViewTask.value = task currentViewType.value = 'before' // è§£ææ°çæ°æ®ç»æ attachmentList.value = [] // ç产åéä»¶ (type=0) if (task.beforeProduction && Array.isArray(task.beforeProduction)) { const beforeFiles = task.beforeProduction.map(file => ({ @@ -895,7 +867,7 @@ })) attachmentList.value.push(...beforeFiles) } // ç产ä¸éä»¶ (type=1) if (task.afterProduction && Array.isArray(task.afterProduction)) { const afterFiles = task.afterProduction.map(file => ({ @@ -904,7 +876,7 @@ })) attachmentList.value.push(...afterFiles) } // ç产åéä»¶ (type=2) if (task.productionIssues && Array.isArray(task.productionIssues)) { const issueFiles = task.productionIssues.map(file => ({ @@ -913,9 +885,9 @@ })) attachmentList.value.push(...issueFiles) } showAttachmentDialog.value = true } catch (error) { uni.showToast({ title: 'è·åé件失败', @@ -943,16 +915,16 @@ } // è·åtypeå¼ const getTabType = () => { switch (currentUploadType.value) { case 'before': return 0 case 'after': return 1 case 'issue': return 2 default: return 0 } switch (currentUploadType.value) { case 'before': return 0 case 'after': return 1 case 'issue': return 2 default: return 0 } } // è·åå½åæ¥çç±»åçéä»¶ const getCurrentViewAttachments = () => { @@ -974,10 +946,10 @@ if (file.contentType && file.contentType.startsWith('image/')) { return true } // æ£æ¥åæçtypeåæ®µ if (file.type === 'image') return true // æ£æ¥æä»¶æ©å±å const name = file.bucketFilename || file.originalFilename || file.name || '' const ext = name.split('.').pop()?.toLowerCase() @@ -991,7 +963,7 @@ const imageUrls = getCurrentViewAttachments() .filter(f => isImageFile(f)) .map(f => f.url || f.downloadUrl) uni.previewImage({ urls: imageUrls, current: file.url || file.downloadUrl @@ -1024,50 +996,50 @@ // 使ç¨ç¸æº const chooseMedia = (type) => { let mediaPamaes={ count: 1, mediaType:[type||'image'], sizeType: ['compressed', 'original'], sourceType: ['camera'], } uni.chooseMedia({ ...mediaPamaes, success: (res) => { try { if (!res.tempFiles || res.tempFiles.length === 0) { throw new Error('æªè·åå°å¾çæä»¶'); } const tempFilePath = res.tempFiles[0]; const tempFile = res.tempFiles && res.tempFiles[0] ? res.tempFiles[0] : {}; const file = { tempFilePath: tempFilePath, path: tempFilePath, // ä¿æå ¼å®¹æ§ type: 'image', name: `photo_${Date.now()}.jpg`, size: tempFile.size || 0, createTime: new Date().getTime(), uid: Date.now() + Math.random() }; handleBeforeUpload(file); } catch (error) { console.error('å¤çæç §ç»æå¤±è´¥:', error); uni.showToast({ title: 'å¤çå¾ç失败', icon: 'error' }); } }, fail: (err) => { console.error('æç §å¤±è´¥:', err); uni.showToast({ title: 'æç §å¤±è´¥: ' + (err.errMsg || 'æªç¥é误'), icon: 'error' }); } }) let mediaPamaes = { count: 1, mediaType: [type || 'image'], sizeType: ['compressed', 'original'], sourceType: ['camera'], } uni.chooseMedia({ ...mediaPamaes, success: (res) => { try { if (!res.tempFiles || res.tempFiles.length === 0) { throw new Error('æªè·åå°å¾çæä»¶'); } const tempFilePath = res.tempFiles[0]; const tempFile = res.tempFiles && res.tempFiles[0] ? res.tempFiles[0] : {}; const file = { tempFilePath: tempFilePath, path: tempFilePath, // ä¿æå ¼å®¹æ§ type: 'image', name: `photo_${Date.now()}.jpg`, size: tempFile.size || 0, createTime: new Date().getTime(), uid: Date.now() + Math.random() }; handleBeforeUpload(file); } catch (error) { console.error('å¤çæç §ç»æå¤±è´¥:', error); uni.showToast({ title: 'å¤çå¾ç失败', icon: 'error' }); } }, fail: (err) => { console.error('æç §å¤±è´¥:', err); uni.showToast({ title: 'æç §å¤±è´¥: ' + (err.errMsg || 'æªç¥é误'), icon: 'error' }); } }) } // æç § @@ -1079,10 +1051,10 @@ }); return; } uni.chooseMedia({ count: 1, mediaType:['image', 'video'], mediaType: ['image', 'video'], sizeType: ['compressed', 'original'], sourceType: ['camera'], success: (res) => { @@ -1090,10 +1062,10 @@ if (!res.tempFiles || res.tempFiles.length === 0) { throw new Error('æªè·åå°å¾çæä»¶'); } const tempFilePath = res.tempFiles[0]; const tempFile = res.tempFiles && res.tempFiles[0] ? res.tempFiles[0] : {}; const file = { tempFilePath: tempFilePath, path: tempFilePath, // ä¿æå ¼å®¹æ§ @@ -1103,7 +1075,7 @@ createTime: new Date().getTime(), uid: Date.now() + Math.random() }; handleBeforeUpload(file); } catch (error) { console.error('å¤çæç §ç»æå¤±è´¥:', error); @@ -1132,7 +1104,7 @@ }); return; } uni.chooseVideo({ sourceType: ['camera'], maxDuration: uploadConfig.maxVideoDuration, @@ -1142,7 +1114,7 @@ if (!res.tempFilePath) { throw new Error('æªè·åå°è§é¢æä»¶'); } const file = { tempFilePath: res.tempFilePath, path: res.tempFilePath, // ä¿æå ¼å®¹æ§ @@ -1153,7 +1125,7 @@ createTime: new Date().getTime(), uid: Date.now() + Math.random() }; handleBeforeUpload(file); } catch (error) { console.error('å¤çæè§é¢ç»æå¤±è´¥:', error); @@ -1256,7 +1228,7 @@ if (uploadConfig.fileType && Array.isArray(uploadConfig.fileType) && uploadConfig.fileType.length > 0) { const fileName = file.name || ''; const fileExtension = fileName ? fileName.split('.').pop().toLowerCase() : ''; // æ ¹æ®æä»¶ç±»åç¡®å®ææçæ©å±å let expectedTypes = []; if (file.type === 'image') { @@ -1264,13 +1236,13 @@ } else if (file.type === 'video') { expectedTypes = ['mp4', 'mov', 'avi', 'wmv']; } // æ£æ¥æä»¶æ©å±åæ¯å¦å¨å 许çç±»åä¸ if (fileExtension && expectedTypes.length > 0) { const isAllowed = expectedTypes.some(type => const isAllowed = expectedTypes.some(type => uploadConfig.fileType.includes(type) && type === fileExtension ); if (!isAllowed) { uni.showToast({ title: `æä»¶æ ¼å¼ä¸æ¯æï¼è¯·ææ ${expectedTypes.join('/')} æ ¼å¼çæä»¶`, @@ -1291,21 +1263,21 @@ uploading.value = true; uploadProgress.value = 0; number.value++; // å¢å ä¸ä¼ è®¡æ° // ç¡®ä¿æä»¶è·¯å¾æ£ç¡® const filePath = file.tempFilePath?.tempFilePath || file.path?.tempFilePath||''; const filePath = file.tempFilePath?.tempFilePath || file.path?.tempFilePath || ''; if (!filePath) { handleUploadError('æä»¶è·¯å¾ä¸åå¨'); return; } // ç¡®ä¿tokenåå¨ const token = getToken(); if (!token) { handleUploadError('ç¨æ·æªç»å½'); return; } // åå¤ä¸ä¼ åæ° const uploadParams = { url: uploadFileUrl.value, @@ -1345,7 +1317,7 @@ fail: (err) => { console.error('ä¸ä¼ 失败:', err.errMsg || err); number.value--; // ä¸ä¼ 失败æ¶åå°è®¡æ° let errorMessage = 'ä¸ä¼ 失败'; if (err.errMsg) { if (err.errMsg.includes('statusCode: null')) { @@ -1358,7 +1330,7 @@ errorMessage = err.errMsg; } } handleUploadError(errorMessage); }, complete: () => { @@ -1366,7 +1338,7 @@ uploadProgress.value = 0; } }); // çå¬ä¸ä¼ è¿åº¦ if (uploadTask && uploadTask.onProgressUpdate) { uploadTask.onProgressUpdate((res) => { @@ -1399,7 +1371,7 @@ const handleUploadSuccess = (res, file) => { if (res.code === 200 && res.data && Array.isArray(res.data) && res.data.length > 0) { const uploadedFile = res.data[0]; // æ ¹æ®å½åä¸ä¼ ç±»å设置typeåæ®µ let typeValue = 0; // é»è®¤ä¸ºç产å switch (currentUploadType.value) { @@ -1413,7 +1385,7 @@ typeValue = 2; break; } // ç¡®ä¿ä¸ä¼ çæä»¶æ°æ®å®æ´ï¼å å«idåtype const fileData = { ...file, @@ -1425,7 +1397,7 @@ createTime: uploadedFile.createTime || new Date().getTime(), type: typeValue // æ·»å ç±»ååæ®µï¼0=ç产å, 1=ç产ä¸, 2=ç产å }; uploadList.value.push(fileData); uploadedSuccessfully(); } else { @@ -1449,7 +1421,7 @@ issueModelValue.value = [...issueModelValue.value, ...uploadList.value]; break; } // éç½®ç¶æ uploadList.value = []; number.value = 0; src/pages/productionManagement/productionReporting/index.vue
@@ -43,7 +43,7 @@ <view class="col"><text class="label">åä½</text><text class="value">{{ item.unit }}</text></view> <view class="col"><text class="label">æäº§æ°é</text><text class="value">{{ item.schedulingNum }}</text></view> <view class="col"><text class="label">ç产æ°é</text><text class="value">{{ item.finishedNum }}</text></view> <view class="col"><text class="label">å¾ ç产æ°é</text><text class="value">{{ item.pendingFinishNum }}</text></view> <view class="col"><text class="label">å¾ æ¥å·¥æ°é</text><text class="value">{{ item.pendingFinishNum }}</text></view> </view> </view> <view class="card_actions"> @@ -70,15 +70,17 @@ import { workListPage } from "@/api/productionManagement/productionReporting.js"; const statusList = reactive([{ text:'å¾ ç产', text:'å¾ æ¥å·¥', value: 1 },{ text:'æäº§ä¸', value: 2 },{ text:'ç产ä¸', value: 3 }]) }, // { // text:'ç产ä¸', // value: 3 // }, ]) const data = reactive({ searchForm: { @@ -90,7 +92,7 @@ const { searchForm } = toRefs(data); const showStatusPicker = ref(false) const statusOptions = ref([ { label: 'å¾ ç产', value: 1 }, { label: 'å¾ æ¥å·¥', value: 1 }, { label: 'ç产ä¸', value: 2 }, { label: 'å·²æ¥å·¥', value: 3 }, ]) @@ -144,7 +146,7 @@ // ç¶æææ¬/ç±»å const statusText = (s) => { if (s == 3) return 'å·²æ¥å·¥' if (s == 1) return 'å¾ ç产' if (s == 1) return 'å¾ æ¥å·¥' return 'ç产ä¸' } const statusType = (s) => {