李志伟 2 年 前
コミット
f76725f443
共有7 個のファイルを変更した235 個の追加46 個の削除を含む
  1. 1
    1
      index.html
  2. 5
    2
      src/components/OrgPicker/index.vue
  3. 120
    0
      src/components/PersonPicker/index.vue
  4. 5
    1
      src/pages/index.vue
  5. 101
    41
      src/pages/invoice/fill.vue
  6. 2
    0
      src/vant.js
  7. 1
    1
      vite.config.js

+ 1
- 1
index.html ファイルの表示

@@ -4,7 +4,7 @@
4 4
     <meta charset="UTF-8" />
5 5
     <link rel="icon" href="/favicon.ico" />
6 6
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
-    <title>Vite App</title>
7
+    <title>电网报销系统</title>
8 8
   </head>
9 9
   <body>
10 10
     <div id="app"></div>

+ 5
- 2
src/components/OrgPicker/index.vue ファイルの表示

@@ -31,7 +31,8 @@ const finished = ref(false)
31 31
 const pageSize = 20
32 32
 
33 33
 const props = defineProps({
34
-  modelValue: String
34
+  modelValue: String,
35
+  invoiceId:String
35 36
 })
36 37
 const emit = defineEmits(['update:modelValue', 'change'])
37 38
 
@@ -73,6 +74,7 @@ const onCancel = () => {
73 74
 // 组件加载, onLoad 就会执行一次
74 75
 // 所以 onMounted 里面不需要初始化执行了
75 76
 const onLoad = () => {
77
+  console.info('----------invoiceId-------->',props.invoiceId)
76 78
   const pageNum = orgResult.value.current ? orgResult.value.current + 1 : 1
77 79
   queryData({ pageNum, pageSize, name: searchValue.value })
78 80
 }
@@ -82,8 +84,9 @@ const onClick = (org) => {
82 84
 }
83 85
 
84 86
 const onSubmit = () => {
87
+  console.info(orgSelected.value)
85 88
   emit('update:modelValue', orgSelected.value.orgId)
86
-  if (orgSelected.value.orgId && orgSelected.value.orgName) {
89
+  if (orgSelected.value.orgId && orgSelected.value.name) {
87 90
     emit('change', orgSelected.value)
88 91
   } else {
89 92
     emit('change')

+ 120
- 0
src/components/PersonPicker/index.vue ファイルの表示

@@ -0,0 +1,120 @@
1
+<template>
2
+  <div class="org-picker">
3
+    <div class="picker-search">
4
+      <van-search v-model="searchValue" placeholder="请输入公司名称" @search="onSearch" />
5
+    </div>
6
+    <div class="picker-list">
7
+      <van-list v-model:loading="loading" :finished="finished" finished-text="我们是有底线的" @load="onLoad">
8
+        <van-cell v-for="org in orgList" :key="org.orgId" :title="org.name" @click="onClick(org)">
9
+          <template #right-icon v-if="org.orgId === orgSelected.orgId">
10
+            <van-icon name="success" />
11
+          </template>
12
+        </van-cell>
13
+      </van-list>
14
+    </div>
15
+    <div class="picker-action">
16
+      <van-button type="primary" @click="onSubmit" block>确定</van-button>
17
+    </div>
18
+  </div>
19
+</template>
20
+
21
+<script setup>
22
+import { computed, watch, ref, onMounted } from 'vue'
23
+import { getOrgList } from '@/services/org'
24
+
25
+
26
+const searchValue = ref('')
27
+const orgSelected = ref({})
28
+const orgResult = ref({})
29
+const loading = ref(false)
30
+const finished = ref(false)
31
+const pageSize = 20
32
+
33
+const props = defineProps({
34
+  modelValue: String,
35
+  invoiceId:String,
36
+  orgId:String
37
+})
38
+const emit = defineEmits(['update:modelValue', 'change'])
39
+
40
+const orgList = computed(() => orgResult.value.records || [])
41
+watch(props.modelValue, (val) => {
42
+  orgSelected.value = { orgId: val }
43
+})
44
+
45
+const queryData = (params) => {
46
+  getOrgList({ ...params, isSystem: true })
47
+    .then((res) => {
48
+      const first = res.current === 1
49
+      if (first) {
50
+        orgResult.value = res
51
+      } else {
52
+        orgResult.value = {
53
+          ...res,
54
+          records: orgResult.value.records.concat(res.records)
55
+        }
56
+      }
57
+
58
+      loading.value = false
59
+      finished.value = res.current >= res.pages
60
+    })
61
+    .catch(() => {
62
+      loading.value = false
63
+      finished.value = true
64
+    })
65
+}
66
+
67
+const onSearch = (val) => {
68
+  queryData({ pageNum: 1, pageSize, name: val })
69
+}
70
+
71
+const onCancel = () => {
72
+  queryData({ pageNum: 1, pageSize })
73
+}
74
+
75
+// 组件加载, onLoad 就会执行一次
76
+// 所以 onMounted 里面不需要初始化执行了
77
+const onLoad = () => {
78
+  console.info('----------invoiceId-------->',props.invoiceId)
79
+  console.info('----------orgId-------->',props.orgId)
80
+  const pageNum = orgResult.value.current ? orgResult.value.current + 1 : 1
81
+  queryData({ pageNum, pageSize, name: searchValue.value })
82
+}
83
+
84
+const onClick = (org) => {
85
+  orgSelected.value = org
86
+}
87
+
88
+const onSubmit = () => {
89
+  console.info(orgSelected.value)
90
+  emit('update:modelValue', orgSelected.value.orgId)
91
+  if (orgSelected.value.orgId && orgSelected.value.name) {
92
+    emit('change', orgSelected.value)
93
+  } else {
94
+    emit('change')
95
+  }
96
+}
97
+
98
+</script>
99
+
100
+<style lang="less" scoped>
101
+.org-picker {
102
+  display: flex;
103
+  flex-direction: column;
104
+  height: 100vh;
105
+  overflow: hidden;
106
+
107
+  .picker-search {
108
+    flex: none;
109
+  }
110
+  .picker-list {
111
+    flex: 1;
112
+    overflow-y: auto;
113
+  }
114
+  .picker-action {
115
+    flex: none;
116
+    box-sizing: border-box;
117
+    padding: 4px 8px;
118
+  }
119
+}
120
+</style>

+ 5
- 1
src/pages/index.vue ファイルの表示

@@ -1,5 +1,9 @@
1 1
 <template>
2
-  <OrgPicker />
2
+  <!-- <OrgPicker /> -->
3
+  <h2 :style="{textAlign:'center'}">电网报销系统</h2>
4
+  <van-button round block type="primary"> 立即申请 </van-button>
5
+  <p></p>
6
+  <van-button round block type="primary"> 我的提交 </van-button>
3 7
 </template>
4 8
 
5 9
 <script setup>

+ 101
- 41
src/pages/invoice/fill.vue ファイルの表示

@@ -1,10 +1,46 @@
1 1
 <template>
2
-  <van-form @failed="onFailed">
2
+  <van-form @failed="onFailed" @submit="onSubmit">
3
+    <h2 :style="{textAlign:'center'}">{{formData.invoiceName}}</h2>
3 4
     <van-cell-group title="开票单位">
4 5
       <van-field
5
-        label="开票单位"
6
+        label="所属公司"
6 7
         v-model="formData.orgName"
7 8
         name="orgName"
9
+        readonly
10
+        @click="showOrgPicker = true"
11
+        placeholder="请输入所属公司"
12
+        :rules="[{ required: true, message: '请输入所属公司' }]"
13
+      />
14
+      <van-popup
15
+        v-model:show="showOrgPicker"
16
+        position="left"
17
+        :style="{ height: '100%', width: '80%' }"
18
+      >
19
+        <org-picker v-model="formData.orgId" :invoiceId="formData.invoiceId" @change="onOrgConfirm" />
20
+      </van-popup>
21
+      <van-field
22
+        label="报销人"
23
+        v-model="formData.personName"
24
+        name="personName"
25
+        readonly
26
+        @click="showPersonPicker = true"
27
+        placeholder="请输入报销人"
28
+        :rules="[{ required: true, message: '请输入报销人' }]"
29
+      />
30
+      <van-popup
31
+        v-model:show="showPersonPicker"
32
+        position="left"
33
+        :style="{ height: '100%', width: '80%' }"
34
+      >
35
+        <person-picker v-model="formData.personId" :invoiceId="formData.invoiceId" :orgId="formData.orgId" @change="onPersonConfirm" />
36
+      </van-popup>
37
+    </van-cell-group>
38
+
39
+    <van-cell-group title="开票单位">
40
+      <van-field
41
+        label="开票单位"
42
+        v-model="formData.invoiceOrg"
43
+        name="invoiceOrg"
8 44
         placeholder="请输入开票单位"
9 45
         :rules="[{ required: true, message: '请输入开票单位' }]"
10 46
       />
@@ -77,7 +113,8 @@
77 113
         </template>
78 114
       </van-cell>
79 115
     </van-cell-group>
80
-    <div style="margin: 16px;">
116
+
117
+    <div style="margin: 16px">
81 118
       <van-button round block type="primary" native-type="submit">
82 119
         提交
83 120
       </van-button>
@@ -86,48 +123,71 @@
86 123
 </template>
87 124
 
88 125
 <script setup>
89
-  import { reactive } from 'vue';
126
+import { reactive, ref } from 'vue';
127
+
128
+const formData = reactive({
129
+  //班级名称
130
+  invoiceName: '电网一班',
131
+  detailId: undefined,
132
+  invoiceId: '好的',
133
+  invoicePersonId: undefined,
134
+  personId: undefined,
135
+  personName: undefined,
136
+  invoiceOrgId: undefined,
137
+  orgId: '66666',
138
+  orgName: undefined,
139
+  invoiceOrg:undefined,
140
+  taxNo: undefined,
141
+  address: undefined,
142
+  phone: undefined,
143
+  bankId: undefined,
144
+  bankName: undefined,
145
+  cardNo: undefined,
146
+  invoiceItemTplId: undefined,
147
+  itemName: undefined,
148
+  charge: undefined,
149
+  mergeRemark: undefined,
150
+  stayRemark: undefined,
151
+})
152
+const showOrgPicker = ref(false)
153
+const showPersonPicker = ref(false)
90 154
 
91
-  const formData = reactive({
92
-    detailId: undefined,
93
-    invoiceId: undefined,
94
-    invoicePersonId: undefined,
95
-    personId: undefined,
96
-    personName: undefined,
97
-    invoiceOrgId: undefined,
98
-    orgId: undefined,
99
-    orgName: undefined,
100
-    taxNo: undefined,
101
-    address: undefined,
102
-    phone: undefined,
103
-    bankId: undefined,
104
-    bankName: undefined,
105
-    cardNo: undefined,
106
-    invoiceItemTplId: undefined,
107
-    itemName: undefined,
108
-    charge: undefined,
109
-    mergeRemark: undefined,
110
-    stayRemark: undefined,
111
-  })
155
+// 校验函数返回 true 表示校验通过,false 表示不通过
156
+const validator = (val) => /1\d{10}/.test(val);
112 157
 
113
-  // 校验函数返回 true 表示校验通过,false 表示不通过
114
-  const validator = (val) => /1\d{10}/.test(val);
158
+// 校验函数可以直接返回一段错误提示
159
+const validatorMessage = (val) => `${val} 不合法,请重新输入`;
115 160
 
116
-  // 校验函数可以直接返回一段错误提示
117
-  const validatorMessage = (val) => `${val} 不合法,请重新输入`;
161
+// 校验函数可以返回 Promise,实现异步校验
162
+const asyncValidator = (val) =>
163
+  new Promise((resolve) => {
164
+    Toast.loading('验证中...');
118 165
 
119
-  // 校验函数可以返回 Promise,实现异步校验
120
-  const asyncValidator = (val) =>
121
-    new Promise((resolve) => {
122
-      Toast.loading('验证中...');
166
+    setTimeout(() => {
167
+      Toast.clear();
168
+      resolve(val === '1234');
169
+    }, 1000);
170
+  });
123 171
 
124
-      setTimeout(() => {
125
-        Toast.clear();
126
-        resolve(val === '1234');
127
-      }, 1000);
128
-    });
172
+const onFailed = (errorInfo) => {
173
+  console.log('failed', formData);
174
+};
175
+const onOrgConfirm = (value) => {
176
+  if (value) {
177
+    formData.orgId = value.orgId
178
+    formData.orgName = value.name
179
+  }
180
+  showOrgPicker.value = false;
181
+};
129 182
 
130
-  const onFailed = (errorInfo) => {
131
-    console.log('failed', errorInfo);
132
-  };
183
+const onPersonConfirm = (value) => {
184
+  if (value) {
185
+    formData.personId = value.orgId
186
+    formData.personName = value.name
187
+  }
188
+  showPersonPicker.value = false;
189
+};
190
+const onSubmit=(val)=>{
191
+  console.info(formData)
192
+}
133 193
 </script>

+ 2
- 0
src/vant.js ファイルの表示

@@ -13,6 +13,7 @@ import {
13 13
   ImagePreview,
14 14
   Search,
15 15
   Toast,
16
+  Popup
16 17
 } from 'vant';
17 18
 
18 19
 import 'vant/es/toast/style';
@@ -34,4 +35,5 @@ export default function vant(app) {
34 35
   app.use(ImagePreview);
35 36
   app.use(Search);
36 37
   app.use(Toast);
38
+  app.use(Popup);
37 39
 }

+ 1
- 1
vite.config.js ファイルの表示

@@ -9,7 +9,7 @@ export default defineConfig({
9 9
   server: {
10 10
     proxy: {
11 11
       '/api': {
12
-        target: 'http://127.0.0.1:7081',
12
+        target: 'http://192.168.89.76:7081',
13 13
         changeOrigin: true,
14 14
       },
15 15
     },