From ed0dd09175513033a41a3bc90d05f683c4809075 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 28 四月 2026 14:48:20 +0800
Subject: [PATCH] 工序管理模块开发
---
src/pages/productionDesign/processManagement/index.vue | 261 +++++++++++++++
src/pages.json | 21 +
src/pages/works.vue | 5
src/pages/productionDesign/processManagement/params.vue | 413 ++++++++++++++++++++++++
src/api/productionManagement/processManagement.js | 80 ++++
src/pages/productionDesign/processManagement/edit.vue | 236 +++++++++++++
6 files changed, 1,016 insertions(+), 0 deletions(-)
diff --git a/src/api/productionManagement/processManagement.js b/src/api/productionManagement/processManagement.js
new file mode 100644
index 0000000..15331ba
--- /dev/null
+++ b/src/api/productionManagement/processManagement.js
@@ -0,0 +1,80 @@
+import request from "@/utils/request";
+
+export function getProcessList(query) {
+ return request({
+ url: "/technologyOperation/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+export function add(data) {
+ return request({
+ url: "/technologyOperation/add",
+ method: "post",
+ data: data,
+ });
+}
+
+export function update(data) {
+ return request({
+ url: "/technologyOperation/update",
+ method: "put",
+ data: data,
+ });
+}
+
+export function del(ids) {
+ return request({
+ url: "/technologyOperation/batchDelete",
+ method: "delete",
+ data: ids,
+ });
+}
+
+export function getProcessParamList(params) {
+ return request({
+ url: "/technologyOperationParam/list",
+ method: "get",
+ params,
+ });
+}
+
+export function addProcessParam(data) {
+ return request({
+ url: "/technologyOperationParam/",
+ method: "post",
+ data: data,
+ });
+}
+
+export function editProcessParam(data) {
+ return request({
+ url: "/technologyOperationParam/",
+ method: "post",
+ data: data,
+ });
+}
+
+export function deleteProcessParam(id) {
+ return request({
+ url: `/technologyOperationParam/batchDelete/${id}`,
+ method: "delete",
+ });
+}
+
+export function getDeviceLedger(query) {
+ return request({
+ url: "/device/ledger/getDeviceLedger",
+ method: "get",
+ params: query,
+ });
+}
+
+export function getBaseParamList(query) {
+ return request({
+ url: "/technologyParam/list",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/pages.json b/src/pages.json
index 1a946d7..d6ade75 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -381,6 +381,27 @@
}
},
{
+ "path": "pages/productionDesign/processManagement/index",
+ "style": {
+ "navigationBarTitleText": "宸ュ簭绠$悊",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/productionDesign/processManagement/edit",
+ "style": {
+ "navigationBarTitleText": "宸ュ簭璇︽儏",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/productionDesign/processManagement/params",
+ "style": {
+ "navigationBarTitleText": "宸ュ簭鍙傛暟閰嶇疆",
+ "navigationStyle": "custom"
+ }
+ },
+ {
"path": "pages/cooperativeOffice/collaborativeApproval/index1",
"style": {
"navigationBarTitleText": "鍏嚭绠$悊",
diff --git a/src/pages/productionDesign/processManagement/edit.vue b/src/pages/productionDesign/processManagement/edit.vue
new file mode 100644
index 0000000..425be43
--- /dev/null
+++ b/src/pages/productionDesign/processManagement/edit.vue
@@ -0,0 +1,236 @@
+<template>
+ <view class="process-edit">
+ <PageHeader :title="pageTitle"
+ @back="goBack" />
+ <up-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ :errorType="['none']"
+ label-width="110">
+ <up-form-item label="宸ュ簭缂栫爜"
+ prop="no">
+ <up-input v-model="form.no"
+ placeholder="璇疯緭鍏ュ伐搴忕紪鐮�"
+ clearable />
+ </up-form-item>
+ <up-form-item label="宸ュ簭鍚嶇О"
+ prop="name"
+ required>
+ <up-input v-model="form.name"
+ placeholder="璇疯緭鍏ュ伐搴忓悕绉�"
+ clearable />
+ </up-form-item>
+ <up-form-item label="宸ヨ祫瀹氶"
+ prop="salaryQuota">
+ <up-input v-model="form.salaryQuota"
+ type="number"
+ placeholder="璇疯緭鍏ュ伐璧勫畾棰�"
+ clearable />
+ </up-form-item>
+ <up-form-item label="璁¤垂绫诲瀷"
+ prop="type">
+ <up-input v-model="typeText"
+ placeholder="璇烽�夋嫨璁¤垂绫诲瀷"
+ readonly
+ @click="showTypeSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showTypeSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="鏄惁璐ㄦ"
+ prop="isQuality">
+ <view style="display: flex; justify-content: flex-end; width: 100%;">
+ <up-switch v-model="form.isQuality" />
+ </view>
+ </up-form-item>
+ <up-form-item label="鏄惁鐢熶骇"
+ prop="isProduction">
+ <view style="display: flex; justify-content: flex-end; width: 100%;">
+ <up-switch v-model="form.isProduction" />
+ </view>
+ </up-form-item>
+ <up-form-item label="鍏宠仈璁惧"
+ prop="deviceLedgerId">
+ <up-input v-model="deviceText"
+ placeholder="璇烽�夋嫨鍏宠仈璁惧"
+ readonly
+ @click="showDeviceSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showDeviceSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="宸ュ簭鎻忚堪"
+ prop="remark">
+ <up-textarea v-model="form.remark"
+ placeholder="璇疯緭鍏ュ伐搴忔弿杩�"
+ autoHeight />
+ </up-form-item>
+ </up-form>
+ <FooterButtons :loading="loading"
+ :confirmText="processId ? '淇濆瓨' : '鏂板'"
+ @cancel="goBack"
+ @confirm="handleSubmit" />
+ <!-- 璁¤垂绫诲瀷閫夋嫨 -->
+ <up-action-sheet :show="showTypeSheet"
+ title="閫夋嫨璁¤垂绫诲瀷"
+ :actions="typeActions"
+ @select="onSelectType"
+ @close="showTypeSheet = false" />
+ <!-- 璁惧閫夋嫨 -->
+ <up-action-sheet :show="showDeviceSheet"
+ title="閫夋嫨鍏宠仈璁惧"
+ :actions="deviceActions"
+ @select="onSelectDevice"
+ @close="showDeviceSheet = false" />
+ </view>
+</template>
+
+<script setup>
+ import { reactive, ref, computed, onMounted } from "vue";
+ import { onLoad, onReady } from "@dcloudio/uni-app";
+ import FooterButtons from "@/components/FooterButtons.vue";
+ import {
+ add,
+ update,
+ getDeviceLedger,
+ } from "@/api/productionManagement/processManagement";
+
+ const formRef = ref(null);
+ const loading = ref(false);
+ const processId = ref(null);
+ const pageTitle = computed(() => (processId.value ? "缂栬緫宸ュ簭" : "鏂板宸ュ簭"));
+
+ const form = ref({
+ no: "",
+ name: "",
+ salaryQuota: "",
+ isQuality: false,
+ isProduction: false,
+ remark: "",
+ deviceLedgerId: null,
+ type: 0,
+ });
+
+ const rules = {
+ name: [{ required: true, message: "璇疯緭鍏ュ伐搴忓悕绉�" }],
+ salaryQuota: [
+ {
+ validator: (rule, value, callback) => {
+ if (value !== "" && value !== null && (isNaN(value) || value < 0)) {
+ callback(new Error("宸ヨ祫瀹氶蹇呴』鏄潪璐熸暟瀛�"));
+ } else {
+ callback();
+ }
+ },
+ },
+ ],
+ };
+
+ const showTypeSheet = ref(false);
+ const typeActions = [
+ { name: "璁℃椂", value: 0 },
+ { name: "璁′欢", value: 1 },
+ ];
+ const typeText = computed(() => {
+ const action = typeActions.find(a => a.value === form.value.type);
+ return action ? action.name : "";
+ });
+
+ const showDeviceSheet = ref(false);
+ const deviceActions = ref([]);
+ const deviceText = ref("");
+
+ const onSelectType = e => {
+ form.value.type = e.value;
+ showTypeSheet.value = false;
+ };
+
+ const onSelectDevice = e => {
+ form.value.deviceLedgerId = e.id;
+ deviceText.value = e.name;
+ showDeviceSheet.value = false;
+ };
+
+ const loadDevices = async () => {
+ try {
+ const { data } = await getDeviceLedger();
+ deviceActions.value = (data || []).map(item => ({
+ name: item.deviceName,
+ id: item.id,
+ }));
+ if (form.value.deviceLedgerId) {
+ const device = deviceActions.value.find(
+ d => d.id === Number(form.value.deviceLedgerId)
+ );
+ if (device) deviceText.value = device.name;
+ }
+ } catch (error) {
+ console.error("鍔犺浇璁惧澶辫触", error);
+ }
+ };
+
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ const handleSubmit = () => {
+ formRef.value
+ .validate()
+ .then(() => {
+ loading.value = true;
+ const promise = processId.value ? update(form.value) : add(form.value);
+ promise
+ .then(() => {
+ uni.showToast({ title: processId.value ? "淇濆瓨鎴愬姛" : "鏂板鎴愬姛" });
+ setTimeout(() => {
+ goBack();
+ }, 1500);
+ })
+ .catch(err => {
+ uni.showToast({ title: err.msg || "鎻愪氦澶辫触", icon: "error" });
+ })
+ .finally(() => {
+ loading.value = false;
+ });
+ })
+ .catch(errors => {
+ if (errors && errors.length > 0) {
+ uni.showToast({
+ title: errors[0].message,
+ icon: "none",
+ });
+ }
+ });
+ };
+
+ onLoad(option => {
+ if (option.item) {
+ const item = JSON.parse(decodeURIComponent(option.item));
+ processId.value = item.id;
+ Object.assign(form.value, item);
+ // 澶勭悊绫诲瀷杞崲锛岀‘淇濇槸鏁板瓧
+ form.value.type = Number(form.value.type);
+ form.value.isQuality = !!form.value.isQuality;
+ form.value.isProduction = !!form.value.isProduction;
+ }
+ });
+
+ onReady(() => {
+ formRef.value.setRules(rules);
+ });
+
+ onMounted(() => {
+ loadDevices();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/static/scss/form-common.scss";
+
+ .process-edit {
+ min-height: 100vh;
+ background: #f5f5f5;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/productionDesign/processManagement/index.vue b/src/pages/productionDesign/processManagement/index.vue
new file mode 100644
index 0000000..6ca2f76
--- /dev/null
+++ b/src/pages/productionDesign/processManagement/index.vue
@@ -0,0 +1,261 @@
+<template>
+ <view class="sales-account">
+ <PageHeader title="宸ュ簭绠$悊"
+ @back="goBack" />
+ <view class="search-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <up-input class="search-text"
+ v-model="queryParams.name"
+ placeholder="璇疯緭鍏ュ伐搴忓悕绉�"
+ clearable
+ @change="handleSearch" />
+ </view>
+ <view class="filter-button"
+ @click="handleSearch">
+ <up-icon name="search"
+ size="24"
+ color="#999999"></up-icon>
+ </view>
+ </view>
+ </view>
+ <view v-if="list.length > 0"
+ class="ledger-list">
+ <view v-for="item in list"
+ :key="item.id"
+ class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="list-dot"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.name || "-" }}</text>
+ </view>
+ <text class="item-index">{{ item.no || "-" }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鍏宠仈璁惧</text>
+ <text class="detail-value">{{ getDeviceName(item.deviceLedgerId) }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸ヨ祫瀹氶</text>
+ <text class="detail-value highlight">楼{{ item.salaryQuota || 0 }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸ュ簭鐘舵��</text>
+ <view class="detail-value">
+ <up-tag :text="item.isQuality ? '璐ㄦ' : '闈炶川妫�'"
+ :type="item.isQuality ? 'warning' : 'info'"
+ size="mini"
+ style="margin-left: 8rpx" />
+ <up-tag :text="item.isProduction ? '鐢熶骇' : '涓嶇敓浜�'"
+ :type="item.isProduction ? 'warning' : 'info'"
+ size="mini"
+ style="margin-left: 8rpx" />
+ <up-tag v-if="item.type !== null && item.type !== undefined"
+ :text="item.type == 0 ? '璁℃椂' : '璁′欢'"
+ :type="item.type == 1 ? 'primary' : 'success'"
+ size="mini"
+ style="margin-left: 8rpx" />
+ </view>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">澶囨敞</text>
+ <text class="detail-value">{{ item.remark || "-" }}</text>
+ </view>
+ </view>
+ <view class="action-buttons">
+ <up-button class="action-btn"
+ size="small"
+ type="primary"
+ @click="goEdit(item)">缂栬緫</up-button>
+ <up-button class="action-btn"
+ size="small"
+ type="warning"
+ @click="goParams(item)">鍙傛暟閰嶇疆</up-button>
+ <up-button class="action-btn"
+ size="small"
+ type="error"
+ @click="handleDelete(item)">鍒犻櫎</up-button>
+ </view>
+ </view>
+ <up-loadmore :status="pageStatus" />
+ </view>
+ <view v-else
+ class="no-data">
+ <text>鏆傛棤宸ュ簭鏁版嵁</text>
+ </view>
+ <view class="fab-button"
+ @click="goAdd">
+ <up-icon name="plus"
+ size="28"
+ color="#ffffff"></up-icon>
+ </view>
+ </view>
+</template>
+
+<script setup>
+ import { reactive, ref } from "vue";
+ import { onReachBottom, onShow } from "@dcloudio/uni-app";
+ import {
+ getProcessList,
+ del,
+ getDeviceLedger,
+ } from "@/api/productionManagement/processManagement";
+
+ const queryParams = reactive({
+ name: "",
+ });
+ const list = ref([]);
+ const deviceOptions = ref([]);
+ const pageStatus = ref("loadmore");
+
+ const page = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+ });
+
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ const getDeviceName = deviceId => {
+ if (!deviceId) return "鏈叧鑱�";
+ const device = deviceOptions.value.find(item => item.id === Number(deviceId));
+ return device?.deviceName || "鏈叧鑱�";
+ };
+
+ const loadDevices = async () => {
+ try {
+ const { data } = await getDeviceLedger();
+ deviceOptions.value = data || [];
+ } catch (error) {
+ console.error("鍔犺浇璁惧鍒楄〃澶辫触", error);
+ }
+ };
+
+ const handleSearch = () => {
+ page.current = 1;
+ pageStatus.value = "loadmore";
+ list.value = [];
+ getList();
+ };
+
+ const getList = () => {
+ if (pageStatus.value === "loading" || pageStatus.value === "nomore") return;
+
+ pageStatus.value = "loading";
+ getProcessList({
+ current: page.current,
+ size: page.size,
+ name: queryParams.name,
+ })
+ .then(res => {
+ const records = res?.data?.records || res?.records || [];
+ const total = res?.data?.total || res?.total || 0;
+
+ if (page.current === 1) {
+ list.value = records;
+ } else {
+ list.value = [...list.value, ...records];
+ }
+
+ page.total = total;
+ if (list.value.length >= total) {
+ pageStatus.value = "nomore";
+ } else {
+ pageStatus.value = "loadmore";
+ page.current++;
+ }
+ })
+ .catch(() => {
+ uni.showToast({ title: "鏌ヨ澶辫触", icon: "error" });
+ pageStatus.value = "loadmore";
+ });
+ };
+
+ const goAdd = () => {
+ uni.navigateTo({ url: "/pages/productionDesign/processManagement/edit" });
+ };
+
+ const goEdit = item => {
+ uni.navigateTo({
+ url: `/pages/productionDesign/processManagement/edit?item=${encodeURIComponent(
+ JSON.stringify(item)
+ )}`,
+ });
+ };
+
+ const goParams = item => {
+ uni.navigateTo({
+ url: `/pages/productionDesign/processManagement/params?id=${item.id}&name=${encodeURIComponent(item.name)}`,
+ });
+ };
+
+ const handleDelete = item => {
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "纭畾瑕佸垹闄よ宸ュ簭鍚楋紵",
+ success: res => {
+ if (res.confirm) {
+ del([item.id]).then(() => {
+ uni.showToast({ title: "鍒犻櫎鎴愬姛" });
+ handleSearch();
+ });
+ }
+ },
+ });
+ };
+
+ onReachBottom(() => {
+ getList();
+ });
+
+ onShow(async () => {
+ await loadDevices();
+ handleSearch();
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/styles/procurement-common.scss";
+
+ .no-data {
+ padding-top: 100rpx;
+ text-align: center;
+ color: #999;
+ font-size: 28rpx;
+ }
+
+ .action-buttons {
+ display: flex;
+ justify-content: flex-end;
+ gap: 20rpx;
+ padding-bottom: 30rpx;
+ }
+
+ .action-btn {
+ flex: 1;
+ margin: 0 !important;
+ }
+
+ .fab-button {
+ position: fixed;
+ right: 40rpx;
+ bottom: 60rpx;
+ width: 100rpx;
+ height: 100rpx;
+ background: #2979ff;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.4);
+ z-index: 100;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/productionDesign/processManagement/params.vue b/src/pages/productionDesign/processManagement/params.vue
new file mode 100644
index 0000000..0fa0bc0
--- /dev/null
+++ b/src/pages/productionDesign/processManagement/params.vue
@@ -0,0 +1,413 @@
+<template>
+ <view class="process-params">
+ <PageHeader :title="processName + ' - 鍙傛暟閰嶇疆'"
+ @back="goBack" />
+ <view class="ledger-list">
+ <view v-if="paramList.length > 0">
+ <view v-for="item in paramList"
+ :key="item.id"
+ class="ledger-item">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="setting-fill"
+ size="16"
+ color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.paramName || "-" }}</text>
+ </view>
+ </view>
+ <up-divider></up-divider>
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鏍囧噯鍊�</text>
+ <text class="detail-value highlight">{{ item.standardValue || "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍗曚綅</text>
+ <text class="detail-value">{{ item.unit || "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙傛暟绫诲瀷</text>
+ <up-tag :text="getParamTypeText(item.paramType)"
+ :type="getParamTypeTag(item.paramType)"
+ size="mini" />
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙栧�兼牸寮�</text>
+ <text class="detail-value">{{ item.paramFormat || "-" }}</text>
+ </view>
+ </view>
+ <view class="action-buttons">
+ <up-button class="action-btn"
+ size="small"
+ type="primary"
+ @click="handleEditParam(item)">缂栬緫</up-button>
+ <up-button class="action-btn"
+ size="small"
+ type="error"
+ @click="handleDeleteParam(item)">鍒犻櫎</up-button>
+ </view>
+ </view>
+ </view>
+ <view v-else
+ class="no-data">
+ <up-empty text="鏆傛棤鍙傛暟閰嶇疆"
+ icon="account"
+ iconSize="60"></up-empty>
+ </view>
+ </view>
+ <!-- 娴姩鏂板鎸夐挳 -->
+ <view class="fab-button"
+ @click="openSelectModal">
+ <up-icon name="plus"
+ size="28"
+ color="#ffffff"></up-icon>
+ </view>
+ <!-- 閫夋嫨鍙傛暟寮圭獥 -->
+ <up-modal :show="selectModalVisible"
+ title="閫夋嫨鍙傛暟"
+ width="650rpx"
+ @confirm="handleSelectSubmit"
+ @cancel="selectModalVisible = false"
+ :closeOnClickOverlay="false"
+ showCancelButton>
+ <view class="modal-content">
+ <view class="search-box">
+ <up-input v-model="searchKeyword"
+ placeholder="鎼滅储鍩虹鍙傛暟鍚嶇О"
+ clearable
+ @confirm="handleSearch"
+ @change="handleSearch" />
+ </view>
+ <scroll-view scroll-y
+ class="param-scroll-list"
+ @scrolltolower="loadMoreParams">
+ <view v-for="param in availableParams"
+ :key="param.id"
+ class="param-select-item"
+ :class="{ active: selectedBaseParam?.id === param.id }"
+ @click="selectParam(param)">
+ <view class="param-main">
+ <text class="param-name">{{ param.paramName }}</text>
+ <up-tag :text="getParamTypeText(param.paramType)"
+ :type="getParamTypeTag(param.paramType)"
+ size="mini" />
+ </view>
+ <text class="param-code">{{ param.paramCode }}</text>
+ </view>
+ <up-loadmore :status="availablePageStatus" />
+ </scroll-view>
+ <view v-if="selectedBaseParam"
+ class="standard-input-box">
+ <text class="label">鏍囧噯鍊硷細</text>
+ <up-input v-model="selectedStandardValue"
+ placeholder="璇疯緭鍏ヨ宸ュ簭鐨勬爣鍑嗗��" />
+ </view>
+ </view>
+ </up-modal>
+ <!-- 缂栬緫鍙傛暟鏍囧噯鍊煎脊绐� -->
+ <up-modal :show="editModalVisible"
+ title="缂栬緫鏍囧噯鍊�"
+ width="500rpx"
+ @confirm="handleEditSubmit"
+ @cancel="editModalVisible = false"
+ :closeOnClickOverlay="false"
+ showCancelButton>
+ <view class="modal-content">
+ <view class="edit-info">
+ <text class="edit-label">鍙傛暟锛歿{ currentEditParam?.paramName }}</text>
+ <up-input v-model="currentEditValue"
+ placeholder="璇疯緭鍏ユ柊鐨勬爣鍑嗗��" />
+ </view>
+ </view>
+ </up-modal>
+ </view>
+</template>
+
+<script setup>
+ import { reactive, ref, onMounted } from "vue";
+ import { onLoad } from "@dcloudio/uni-app";
+ import {
+ getProcessParamList,
+ addProcessParam,
+ editProcessParam,
+ deleteProcessParam,
+ getBaseParamList,
+ } from "@/api/productionManagement/processManagement";
+
+ const processId = ref(null);
+ const processName = ref("");
+ const paramList = ref([]);
+ const loading = ref(false);
+
+ // 閫夋嫨鍙傛暟鐩稿叧
+ const selectModalVisible = ref(false);
+ const availableParams = ref([]);
+ const searchKeyword = ref("");
+ const selectedBaseParam = ref(null);
+ const selectedStandardValue = ref("");
+ const availablePage = reactive({ current: 1, size: 20, total: 0 });
+ const availablePageStatus = ref("loadmore");
+
+ // 缂栬緫鍙傛暟鐩稿叧
+ const editModalVisible = ref(false);
+ const currentEditParam = ref(null);
+ const currentEditValue = ref("");
+
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ const getParamList = () => {
+ loading.value = true;
+ getProcessParamList({ technologyOperationId: processId.value })
+ .then(res => {
+ paramList.value = res?.data || [];
+ })
+ .catch(() => {
+ uni.showToast({ title: "鑾峰彇鍒楄〃澶辫触", icon: "none" });
+ })
+ .finally(() => {
+ loading.value = false;
+ });
+ };
+
+ const openSelectModal = () => {
+ searchKeyword.value = "";
+ selectedBaseParam.value = null;
+ selectedStandardValue.value = "";
+ availableParams.value = [];
+ availablePage.current = 1;
+ availablePageStatus.value = "loadmore";
+ selectModalVisible.value = true;
+ loadAvailableParams(true);
+ };
+
+ const handleSearch = () => {
+ availablePage.current = 1;
+ availableParams.value = [];
+ availablePageStatus.value = "loadmore";
+ loadAvailableParams(true);
+ };
+
+ const loadMoreParams = () => {
+ if (
+ availablePageStatus.value === "nomore" ||
+ availablePageStatus.value === "loading"
+ )
+ return;
+ loadAvailableParams(false);
+ };
+
+ const loadAvailableParams = (isReset = false) => {
+ if (availablePageStatus.value === "loading") return;
+ if (isReset) {
+ availablePage.current = 1;
+ availableParams.value = [];
+ availablePageStatus.value = "loading";
+ } else if (availablePageStatus.value === "nomore") {
+ return;
+ } else {
+ availablePageStatus.value = "loading";
+ }
+ getBaseParamList({
+ paramName: searchKeyword.value,
+ current: availablePage.current,
+ size: availablePage.size,
+ })
+ .then(res => {
+ const records = res?.data?.records || res?.records || [];
+ const total = res?.data?.total || res?.total || 0;
+
+ if (isReset || availablePage.current === 1) {
+ availableParams.value = records;
+ } else {
+ availableParams.value = [...availableParams.value, ...records];
+ }
+
+ availablePage.total = total;
+ if (availableParams.value.length >= total) {
+ availablePageStatus.value = "nomore";
+ } else {
+ availablePageStatus.value = "loadmore";
+ availablePage.current++;
+ }
+ })
+ .catch(() => {
+ availablePageStatus.value = "loadmore";
+ });
+ };
+
+ const selectParam = param => {
+ selectedBaseParam.value = param;
+ selectedStandardValue.value = param.standardValue || "";
+ };
+
+ const handleSelectSubmit = () => {
+ if (!selectedBaseParam.value) {
+ uni.showToast({ title: "璇烽�夋嫨涓�涓熀纭�鍙傛暟", icon: "none" });
+ return;
+ }
+ if (!selectedStandardValue.value) {
+ uni.showToast({ title: "璇疯緭鍏ユ爣鍑嗗��", icon: "none" });
+ return;
+ }
+ addProcessParam({
+ technologyOperationId: processId.value,
+ technologyParamId: selectedBaseParam.value.id,
+ standardValue: selectedStandardValue.value,
+ })
+ .then(() => {
+ uni.showToast({ title: "娣诲姞鎴愬姛" });
+ selectModalVisible.value = false;
+ getParamList();
+ })
+ .catch(err => {
+ uni.showToast({ title: err.msg || "娣诲姞澶辫触", icon: "error" });
+ });
+ };
+
+ const handleEditParam = item => {
+ currentEditParam.value = item;
+ currentEditValue.value = item.standardValue;
+ editModalVisible.value = true;
+ };
+
+ const handleEditSubmit = () => {
+ if (!currentEditValue.value) {
+ uni.showToast({ title: "璇疯緭鍏ユ爣鍑嗗��", icon: "none" });
+ return;
+ }
+ editProcessParam({
+ id: currentEditParam.value.id,
+ technologyOperationId: processId.value,
+ technologyParamId: currentEditParam.value.technologyParamId,
+ standardValue: currentEditValue.value,
+ })
+ .then(() => {
+ uni.showToast({ title: "淇敼鎴愬姛" });
+ editModalVisible.value = false;
+ getParamList();
+ })
+ .catch(err => {
+ uni.showToast({ title: err.msg || "淇敼澶辫触", icon: "error" });
+ });
+ };
+
+ const handleDeleteParam = item => {
+ uni.showModal({
+ title: "鎻愮ず",
+ content: "纭畾瑕佸垹闄よ鍙傛暟閰嶇疆鍚楋紵",
+ success: res => {
+ if (res.confirm) {
+ deleteProcessParam(item.id).then(() => {
+ uni.showToast({ title: "鍒犻櫎鎴愬姛" });
+ getParamList();
+ });
+ }
+ },
+ });
+ };
+
+ const getParamTypeText = type => {
+ const typeMap = { 1: "鏁板��", 2: "鏂囨湰", 3: "涓嬫媺", 4: "鏃堕棿" };
+ return typeMap[type] || "鏈煡";
+ };
+
+ const getParamTypeTag = type => {
+ const typeMap = { 1: "primary", 2: "info", 3: "warning", 4: "success" };
+ return typeMap[type] || "default";
+ };
+
+ onLoad(option => {
+ if (option.id) {
+ processId.value = option.id;
+ processName.value = decodeURIComponent(option.name || "");
+ getParamList();
+ }
+ });
+</script>
+
+<style scoped lang="scss">
+ @import "@/styles/procurement-common.scss";
+
+ .process-params {
+ min-height: 100vh;
+ background: #f5f5f5;
+ }
+
+ .modal-content {
+ padding: 20rpx 0;
+ width: 100%;
+ }
+
+ .param-scroll-list {
+ height: 500rpx;
+ margin-top: 20rpx;
+ border: 1px solid #eee;
+ border-radius: 8rpx;
+ }
+
+ .param-select-item {
+ padding: 20rpx;
+ border-bottom: 1px solid #f5f5f5;
+ width: 100%;
+ &.active {
+ background-color: #e3f2fd;
+ }
+ }
+
+ .param-main {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8rpx;
+ }
+
+ .param-name {
+ font-size: 28rpx;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .param-code {
+ font-size: 24rpx;
+ color: #999;
+ }
+
+ .standard-input-box {
+ margin-top: 30rpx;
+ display: flex;
+ align-items: center;
+ .label {
+ width: 120rpx;
+ font-size: 28rpx;
+ color: #333;
+ }
+ }
+
+ .edit-info {
+ .edit-label {
+ display: block;
+ margin-bottom: 20rpx;
+ font-size: 28rpx;
+ color: #666;
+ }
+ }
+
+ .fab-button {
+ position: fixed;
+ right: 40rpx;
+ bottom: 60rpx;
+ width: 100rpx;
+ height: 100rpx;
+ background: #2979ff;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.4);
+ z-index: 100;
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/works.vue b/src/pages/works.vue
index 72f1d0a..ee32b41 100644
--- a/src/pages/works.vue
+++ b/src/pages/works.vue
@@ -996,6 +996,11 @@
url: "/pages/productionDesign/basicParameters/index",
});
break;
+ case "宸ュ簭绠$悊":
+ uni.navigateTo({
+ url: "/pages/productionDesign/processManagement/index",
+ });
+ break;
default:
uni.showToast({
title: `鐐瑰嚮浜�${item.label}`,
--
Gitblit v1.9.3