| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- <template>
- <SidebarLayout
- :menuItems="menuItems"
- :userName="authStore.user?.name"
- :activeKey="'prices'"
- @logout="handleLogout"
- >
- <div class="prices-page">
- <a-card>
- <a-space>
- <a-select v-model:value="filterWorkOrderId" placeholder="筛选工单" style="width: 250px" allowClear @change="loadPrices">
- <a-select-option v-for="wo in workOrders" :key="wo.id" :value="wo.id">
- {{ wo.order_no }} - {{ wo.style_name }}
- </a-select-option>
- </a-select>
- <a-button type="primary" @click="showCreateModal">设置工价</a-button>
- </a-space>
- </a-card>
- <a-card class="mt-4" title="工价列表">
- <a-table :columns="columns" :dataSource="prices" :loading="loading" rowKey="id">
- <template #price="{ record }">
- ¥{{ record.price.toFixed(2) }}
- </template>
- <template #action="{ record }">
- <a-space>
- <a-button size="small" @click="showEditModal(record)">编辑</a-button>
- <a-popconfirm title="删除此工价?" @confirm="deletePrice(record.id)">
- <a-button size="small" danger>删除</a-button>
- </a-popconfirm>
- </a-space>
- </template>
- </a-table>
- </a-card>
- <!-- 创建/编辑工价模态框 -->
- <a-modal v-model:open="modalVisible" :title="modalTitle" @ok="handleSubmit" :confirmLoading="submitting">
- <a-form ref="formRef" :model="formState" :rules="formRules" layout="vertical">
- <a-form-item label="款号" name="style" v-if="!isEdit">
- <a-input v-model:value="formState.style" placeholder="请输入款号" />
- </a-form-item>
- <a-form-item label="工序" name="process_id">
- <a-select v-model:value="formState.process_id" placeholder="请选择工序">
- <a-select-option v-for="p in processes" :key="p.id" :value="p.id">
- {{ p.name }} ({{ p.code }})
- </a-select-option>
- </a-select>
- </a-form-item>
- <a-form-item label="工价(元)" name="price">
- <a-input-number v-model:value="formState.price" :min="0" :max="10000" :step="0.1" style="width: 100%" />
- </a-form-item>
- <a-form-item label="备注" name="remark">
- <a-textarea v-model:value="formState.remark" :rows="2" placeholder="可选" />
- </a-form-item>
- </a-form>
- </a-modal>
- </div>
- </SidebarLayout>
- </template>
- <script setup lang="ts">
- import { ref, reactive, onMounted } from 'vue';
- import { useRouter } from 'vue-router';
- import { message } from 'ant-design-vue';
- import { useAuthStore } from '@/stores/auth';
- import { SidebarLayout } from '@smartcut/shared-components';
- import { WorkOrderApi, ProcessApi, createApiClient } from '@smartcut/api-client';
- import { STORAGE_KEYS } from '@smartcut/shared-utils';
- import type { WorkOrder, Process, PriceTemplate } from '@smartcut/types';
- const router = useRouter();
- const authStore = useAuthStore();
- const menuItems = [
- { key: 'dashboard', label: '主页看板', icon: 'DashboardOutlined', path: '/' },
- { key: 'work-orders', label: '工单管理', icon: 'FileOutlined', path: '/work-orders' },
- { key: 'processes', label: '工序管理', icon: 'AppstoreOutlined', path: '/processes' },
- { key: 'records', label: '计件记录', icon: 'UnorderedListOutlined', path: '/records' },
- { key: 'salary', label: '工资管理', icon: 'PayCircleOutlined', path: '/salary' },
- { key: 'users', label: '用户管理', icon: 'UserOutlined', path: '/users' }
- ];
- const apiClient = createApiClient({
- baseURL: window.location.origin,
- tokenKey: STORAGE_KEYS.FACTORY_TOKEN
- });
- const workOrderApi = new WorkOrderApi(apiClient);
- const processApi = new ProcessApi(apiClient);
- const prices = ref<PriceTemplate[]>([]);
- const workOrders = ref<WorkOrder[]>([]);
- const processes = ref<Process[]>([]);
- const loading = ref(false);
- const filterWorkOrderId = ref<number | null>(null);
- const columns = [
- { title: 'ID', dataIndex: 'id', key: 'id', width: 80 },
- { title: '款号', dataIndex: 'style', key: 'style', width: 120 },
- { title: '工序', dataIndex: 'process_name', key: 'process_name', width: 150 },
- { title: '工价', key: 'price', width: 100, slots: { customRender: 'price' } },
- { title: '备注', dataIndex: 'remark', key: 'remark', width: 200 },
- { title: '操作', key: 'action', width: 150, slots: { customRender: 'action' } }
- ];
- const modalVisible = ref(false);
- const modalTitle = ref('设置工价');
- const isEdit = ref(false);
- const submitting = ref(false);
- const formRef = ref();
- const editingId = ref<number | null>(null);
- const formState = reactive({
- style: '',
- process_id: null as number | null,
- price: 0,
- remark: ''
- });
- const formRules = {
- style: [{ required: true, message: '请输入款号', trigger: 'blur' }],
- process_id: [{ required: true, message: '请选择工序', trigger: 'change' }],
- price: [{ required: true, message: '请输入工价', trigger: 'blur' }]
- };
- async function loadPrices() {
- loading.value = true;
- try {
- const params: any = {};
- if (filterWorkOrderId.value) params.work_order_id = filterWorkOrderId.value;
- const response = await apiClient.get('/prices', { params });
- prices.value = response.data.data || [];
- } catch (error) {
- message.error('加载工价列表失败');
- } finally {
- loading.value = false;
- }
- }
- async function loadWorkOrders() {
- try {
- const result = await workOrderApi.getWorkOrders({ page: 1, page_size: 100 });
- workOrders.value = result.list;
- } catch (error) {
- // ignore
- }
- }
- async function loadProcesses() {
- try {
- processes.value = await processApi.getProcesses();
- } catch (error) {
- // ignore
- }
- }
- function showCreateModal() {
- modalTitle.value = '设置工价';
- isEdit.value = false;
- modalVisible.value = true;
- formRef.value?.resetFields();
- formState.style = '';
- formState.process_id = null;
- formState.price = 0;
- formState.remark = '';
- }
- function showEditModal(record: PriceTemplate) {
- modalTitle.value = '编辑工价';
- isEdit.value = true;
- editingId.value = record.id;
- modalVisible.value = true;
- formState.style = record.style;
- formState.process_id = record.process_id;
- formState.price = record.price;
- formState.remark = record.remark;
- }
- async function handleSubmit() {
- try {
- await formRef.value.validate();
- submitting.value = true;
- if (isEdit.value && editingId.value) {
- await apiClient.put(`/prices/${editingId.value}`, {
- process_id: formState.process_id,
- price: formState.price,
- remark: formState.remark
- });
- message.success('工价已更新');
- } else {
- await apiClient.post('/prices', {
- style: formState.style,
- process_id: formState.process_id,
- price: formState.price,
- remark: formState.remark
- });
- message.success('工价已创建');
- }
- modalVisible.value = false;
- loadPrices();
- } catch (error: any) {
- message.error(error.response?.data?.msg || '操作失败');
- } finally {
- submitting.value = false;
- }
- }
- async function deletePrice(id: number) {
- try {
- await apiClient.delete(`/prices/${id}`);
- message.success('工价已删除');
- loadPrices();
- } catch (error) {
- message.error('删除失败');
- }
- }
- function handleLogout() {
- authStore.logout();
- message.success('已退出登录');
- router.push('/login');
- }
- onMounted(() => {
- loadPrices();
- loadWorkOrders();
- loadProcesses();
- });
- </script>
- <style scoped lang="postcss">
- .prices-page { padding: 0; }
- .mt-4 { margin-top: 16px; }
- </style>
|