index.vue 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  1. <template>
  2. <div>
  3. <van-nav-bar title="费用报销" left-text="返回" @click-left="back" fixed left-arrow style="z-index:1000" />
  4. <div class="content">
  5. <van-tabs v-model="active" @change="activeChange">
  6. <van-tab title="费用报销" :name="0"></van-tab>
  7. <van-tab title="单据列表" :name="1"></van-tab>
  8. <van-tab title="单据审核" :name="2"></van-tab>
  9. </van-tabs>
  10. <!-- #region 费用报销 -->
  11. <div class="edit" v-if="active == 0">
  12. <van-form class="edit_form" label-width="140">
  13. <!-- 报销人 -->
  14. <van-field label="报销人" @click="ownerIdShowCli(1)" readonly clickable required>
  15. <template #input>
  16. <span v-if="user.userNameNeedTranslate == 1 && formshowText.name"><TranslationOpenDataText type='userName'
  17. :openid='formshowText.name'></TranslationOpenDataText></span>
  18. <span v-else>{{ formshowText.name }}</span>
  19. </template>
  20. </van-field>
  21. <div v-if="auditTypeItem.auditType == 2">
  22. <van-field label="第一审核人" @click="ownerIdShowCli(2)" readonly clickable required :disabled="editForm.type == '14454'">
  23. <template #input>
  24. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  25. :openid='firstCheckerText.name'></TranslationOpenDataText></span>
  26. <span v-else>{{ firstCheckerText.name }}</span>
  27. </template>
  28. </van-field>
  29. <van-field label="第二审核人" @click="ownerIdShowCli(3)" readonly clickable required :disabled="editForm.type == '14454'">
  30. <template #input>
  31. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  32. :openid='secondCheckerText.name'></TranslationOpenDataText></span>
  33. <span v-else>{{ secondCheckerText.name }}</span>
  34. </template>
  35. </van-field>
  36. </div>
  37. <van-popup v-model="ownerIdShow" position="bottom" v-if="canExamine" style="height: 90%">
  38. <div class="popupDiv paddingTop">
  39. <div class="popupCon conBorder">
  40. <van-radio-group v-model="userRadio" v-if="user.userNameNeedTranslate == '1'">
  41. <div v-for="item in userList" :key="item.id">
  42. <van-radio :name="item" class="popupItem marginNone borderNone" v-if="item.id != user.id || ownerIdShowType == 1">
  43. <!-- <TranslationOpenDataText type='userName' :openid='item.name'></TranslationOpenDataText> -->
  44. <span class="userNameClass_left">
  45. <TranslationOpenDataText type='userName' :openid='item.name'></TranslationOpenDataText>
  46. </span>
  47. <span class="userNameClass_right">
  48. {{ item.jobNumber }}
  49. </span>
  50. </van-radio>
  51. </div>
  52. </van-radio-group>
  53. <van-radio-group v-model="userRadio" v-else>
  54. <div v-for="item in userList" :key="item.id">
  55. <van-radio :name="item" class="popupItem marginNone borderNone" v-if="item.id != user.id || ownerIdShowType == 1">
  56. <!-- {{ item.name }} -->
  57. <span class="userNameClass_left">{{item.name}}</span>
  58. <span class="userNameClass_right">{{ item.jobNumber }}</span>
  59. </van-radio>
  60. </div>
  61. </van-radio-group>
  62. </div>
  63. <div class="popupBtn">
  64. <van-button style="width:100%;background: #1989fa;color: #ffffff;" round
  65. @click="ownerIdChange()">确定</van-button>
  66. </div>
  67. </div>
  68. </van-popup>
  69. <!-- 填报日期 -->
  70. <van-field v-model="editForm.createDate" label="填报日期" @click="createDateShow = true" readonly clickable
  71. required></van-field>
  72. <van-popup v-model="createDateShow" position="bottom">
  73. <van-datetime-picker type="date" title="选择填报日期" @confirm="createDateChange" v-model="currentDate1"
  74. @cancel="createDateShow = false; $forceUpdate();" :min-date="minDate" :max-date="maxDate" />
  75. </van-popup>
  76. <!-- 发票张数 -->
  77. <van-field label="发票张数" v-if="user.timeType.easyExpense==0 && editForm.type != '14454'">
  78. <template #input>
  79. <van-stepper v-model="editForm.ticketNum" disable-input @plus="ticNumChange(1)"
  80. @minus="ticNumChange(0)" />
  81. </template>
  82. </van-field>
  83. <!-- 费用类型 -->
  84. <van-field v-model="editForm.type" label="费用主类型" @click="typeShow = true" readonly clickable>
  85. <template #input>{{ expenseMainType.text }}</template>
  86. </van-field>
  87. <van-popup v-model="typeShow" position="bottom">
  88. <van-picker show-toolbar :columns="typeList" @confirm="typeChange"
  89. @cancel="typeShow = false; $forceUpdate();" />
  90. </van-popup>
  91. <van-field label="设备归属人" @click="equipmentOwnershipVisable = true" readonly clickable required v-if="editForm.type == '14454'">
  92. <template #input>
  93. <span>{{ equipmentOwner.name }}</span>
  94. </template>
  95. </van-field>
  96. <van-popup v-model="equipmentOwnershipVisable" position="bottom">
  97. <van-picker show-toolbar :columns="equipmentOwnerList" @confirm="deviceTypeChange"
  98. @cancel="equipmentOwnershipVisable = false; $forceUpdate();" />
  99. </van-popup>
  100. <!-- 备注 -->
  101. <van-field v-model="editForm.remark" label="备注" type="textarea" maxlength="100" :disabled="editForm.type == '14454'"></van-field>
  102. <!-- 发票 -->
  103. <van-field label="发票" readonly>
  104. <template #input>总费用: ¥{{ totalCost }}</template>
  105. </van-field>
  106. <div class="invoice" v-if="invoiceList.length != 0">
  107. <div v-for="item, index in invoiceList" :key="item.id" style="position:relative"
  108. :class="index == 0 ? '' : 'invoice_item'">
  109. <!-- <van-button class="deletebtn" size="mini" type="default" @click="deleteInvoice(index)">删除</van-button> -->
  110. <van-icon name="delete-o" class="deletebtn" v-if="index != 0" @click="deleteInvoice(index)" />
  111. <van-field label="所属项目:" v-model="item.projectId"
  112. @click="in_projectShow = true, invoiceIndex = index" readonly clickable required>
  113. <template #input>{{ formshowText.inProjectName[index] }}</template>
  114. </van-field>
  115. <van-field label="费用日期:" v-model="item.happenDate"
  116. @click="in_dateShow = true, invoiceIndex = index" readonly clickable required></van-field>
  117. <template v-if="!(user.companyId == mechanicalCompanyId && user.id != editForm.ownerId && editForm.type == 14454)">
  118. <van-field label="发票种类:" v-model="item.invoiceType" v-if="user.timeType.easyExpense==0"
  119. @click="in_typeShow = true, invoiceIndex = index" readonly clickable required>
  120. <template #input>{{ inTypeList[item.invoiceType] }}</template>
  121. </van-field>
  122. </template>
  123. <van-field label="费用类型:" v-model="item.expenseType"
  124. @click="in_exTypeShow = true, invoiceIndex = index" readonly clickable required></van-field>
  125. <template v-if="!(user.companyId == mechanicalCompanyId && user.id != editForm.ownerId && editForm.type == 14454)">
  126. <van-field :label="`${user.timeType.easyExpense==0?'费用金额(含税)':'费用金额'}:`" v-model="item.amount" type="number" required></van-field>
  127. <van-field label="发票号:" v-model="item.invoiceNo" v-if="user.timeType.easyExpense==0"></van-field>
  128. <van-field label="税率%:" v-model="item.taxPercent" v-if="user.timeType.easyExpense==0"></van-field>
  129. <van-field label="税额:" readonly v-if="user.timeType.easyExpense==0">
  130. <template #input>¥{{ getTaxValue(item.amount, item.taxPercent) }}</template>
  131. </van-field>
  132. <van-field label="备注:" v-model="item.remark" autosize maxlength="100"></van-field>
  133. <!-- <van-field label="报销凭证:" @click="invoiceIndex = index" clickable>
  134. <template #input>
  135. <van-uploader v-model="uploader[index]" :before-read="beforeRead"
  136. :after-read="afterRead" @delete="item.pic = null" :max-count="1" />
  137. </template>
  138. </van-field> -->
  139. <van-field @click="invoiceIndex = index" clickable label-width="0em">
  140. <template #input>
  141. <div class="imgListVan">
  142. <div>报销凭证:</div>
  143. <div class="vanUploaderImg">
  144. <van-uploader v-model="uploader[index]" :before-read="beforeRead" multiple
  145. :after-read="afterRead" @delete="(file, Item) => {deteleImg(file, Item, index)}" :max-count="10" />
  146. </div>
  147. </div>
  148. </template>
  149. </van-field>
  150. </template>
  151. </div>
  152. </div>
  153. <div class="addinvoice"><van-button size="small" icon="plus" type="info" plain hairline
  154. @click="addInvoice">添加发票</van-button></div>
  155. <!-- 发票-popup -->
  156. <span>
  157. <!-- 所属项目 -->
  158. <!-- <van-popup v-model="in_projectShow" position="bottom">
  159. <van-picker value-key="projectName" show-toolbar :columns="inProjectList"
  160. @confirm="inProjectChange" @cancel="in_projectShow = false; $forceUpdate();" />
  161. </van-popup> -->
  162. <van-popup v-model="in_projectShow" position="bottom" style="height: 84%">
  163. <div class="popupDiv">
  164. <div class="popupSearch">
  165. <van-search v-model.trim="projectSelectVal" shape="round" background="#F4F4F4" placeholder="请输入项目名称/编号" @clear="projectSelect()" @blur="projectSelect()" @search="projectSelect()" @input="projectSelect()"/>
  166. </div>
  167. <div class="popupCon">
  168. <div v-for="(item, index) in inProjectList" :key="item.id" class="popupItem paddingDiv" @click="inProjectChange(item, index)">
  169. <p class="popupItemOne" v-if="item.projectName">{{item.projectName}}</p>
  170. <p class="popupItemTwo" v-if="item.projectCode">{{item.projectCode}}</p>
  171. </div>
  172. </div>
  173. </div>
  174. </van-popup>
  175. <!-- 费用日期 -->
  176. <van-popup v-model="in_dateShow" position="bottom">
  177. <van-datetime-picker type="date" title="选择费用日期" @confirm="inDateChange" v-model="currentDate2"
  178. @cancel="in_dateShow = false; $forceUpdate();" :min-date="minDate" :max-date="maxDate" />
  179. </van-popup>
  180. <!-- 发票种类 -->
  181. <van-popup v-model="in_typeShow" position="bottom">
  182. <van-picker show-toolbar :columns="inTypeList" @confirm="inTypeChange"
  183. @cancel="in_typeShow = false; $forceUpdate();" />
  184. </van-popup>
  185. <!-- 费用类型 -->
  186. <van-popup v-model="in_exTypeShow" position="bottom">
  187. <van-picker value-key="typeName" show-toolbar :columns="inexTypeList" @confirm="inexTypeChange"
  188. @cancel="in_exTypeShow = false; $forceUpdate();" />
  189. </van-popup>
  190. </span>
  191. </van-form>
  192. <!-- 提交 -->
  193. <div class="form_btn" style="position:fixed; bottom:0px;width:100%;">
  194. <div style="padding-bottom:10px;">
  195. <van-button square block type="info" @click="submitExpense" :loading="confirmLoading"
  196. style="width:100%;float:left;">提交</van-button>
  197. </div>
  198. </div>
  199. </div>
  200. <!-- #endregion -->
  201. <!-- 单据列表 -->
  202. <div class="list" v-if="active == 1">
  203. <!-- <van-pull-refresh v-model="downLoading" @refresh="onDownRefresh">
  204. <van-list v-model="uploading" :finished="upFinished" :immediate-check="false" :offset="100" finished-text="没有更多了" @load="onLoadList"></van-list>
  205. </van-pull-refresh> -->
  206. <van-collapse v-model="activeName" accordion class="list_collapse">
  207. <van-collapse-item v-for="item in billList" :key="item.id" title="标题1" :name="item.id">
  208. <template #title>
  209. <div class="collapse_label_l">票据编号:{{ item.code }}</div>
  210. <div class="collapse_label_r">报销人:
  211. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  212. :openid='item.ownerName'></TranslationOpenDataText></span>
  213. <span v-else>{{ item.ownerName }}</span>
  214. </div>
  215. <div class="collapse_label_l">金额: ¥{{ item.totalAmount | numtosum }}</div>
  216. <div class="collapse_label_r">状态:<span :class="statusClass[item.status]">{{
  217. statusList[item.status] }}</span></div>
  218. </template>
  219. <div class="wrapper">
  220. <div><span>{{ user.companyId == mechanicalCompanyId ? '工程名称' : '项目名称'}}:</span><span>{{ item.engineeringName }}</span></div>
  221. <div><span>票据编号:</span><span>{{ item.code }}</span></div>
  222. <div><span>金额:</span><span>¥{{ item.totalAmount | numtosum }}</span></div>
  223. <div><span>报销人:</span>
  224. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  225. :openid='item.ownerName'></TranslationOpenDataText></span>
  226. <span v-else>{{ item.ownerName }}</span>
  227. </div>
  228. <div><span>填报日期:</span><span>{{ item.createDate }}</span></div>
  229. <div v-if="user.timeType.easyExpense==0 && item.type != 14454"><span>发票张数:</span><span>{{ item.ticketNum }}</span></div>
  230. <div><span>费用类型:</span><span>{{ item.expenseMainTypeName }}</span></div>
  231. <!-- <div><span>状态:</span><span>{{item.status}}</span></div> -->
  232. <!-- <div><span>驳回原因:</span><span>{{item.denyReason}}</span></div> -->
  233. <div>
  234. <span>审核流程:</span>
  235. <span v-if="item.reviewProcess == 0">待第一审核人审核</span>
  236. <span v-if="item.reviewProcess == 1">待第二审核人审核</span>
  237. <span v-if="item.reviewProcess == 2">审核完成</span>
  238. <span v-if="item.reviewProcess == 3">未提交</span>
  239. <span v-if="item.reviewProcess == 4">已驳回</span>
  240. </div>
  241. <div v-if="item.type == 14454"><span>设备归属人:</span><span>{{ item.equipmentOwnerName }}</span></div>
  242. <div><span>备注:</span><span>{{ item.remark }}</span></div>
  243. </div>
  244. <div class="operation">
  245. <van-button size="small" type="info"
  246. :to="{ name: 'expenseDetails', params: { id: item.id, canEdit: false } }">查看</van-button>
  247. <template v-if="item.status != 0">
  248. <van-button style="margin-left:10px" size="small" type="info"
  249. :to="{ name: 'expenseDetails', params: { id: item.id, canEdit: true } }" v-if="item.type != 14454">编辑</van-button>
  250. <van-button style="margin-left:10px" size="small" type="info"
  251. :to="{ name: 'customizedDetail', params: { id: item.id, canEdit: true } }" v-if="item.type == 14454">编辑</van-button>
  252. </template>
  253. <van-button style="margin-left:10px" size="small" type="danger"
  254. @click="deleteBill(item.id)">删除</van-button>
  255. </div>
  256. </van-collapse-item>
  257. </van-collapse>
  258. </div>
  259. <!-- 单据审核 -->
  260. <div class="audit" v-if="active == 2">
  261. <van-collapse v-model="auditName" accordion class="list_collapse">
  262. <van-collapse-item v-for="item in examineList" :key="item.id" title="标题2" :name="item.id">
  263. <template #title>
  264. <div class="collapse_label_l">票据编号:{{ item.code }}</div>
  265. <div class="collapse_label_r">报销人:
  266. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  267. :openid='item.ownerName'></TranslationOpenDataText></span>
  268. <span v-else>{{ item.ownerName }}</span>
  269. </div>
  270. <div class="collapse_label_l">金额: ¥{{ item.totalAmount | numtosum }}</div>
  271. <div class="collapse_label_r">状态:<span :class="statusClass[item.status]">{{
  272. statusList[item.status] }}</span></div>
  273. <div class="operation" v-if="auditTypeItem.auditType == 0">
  274. <van-button size="small" type="info" :loading="item.approveLoading"
  275. @click.stop="approve(item)">通过</van-button>
  276. <van-button style="margin-left:15px" size="small" type="danger"
  277. @click.stop="denyToReason(item.id)">驳回</van-button>
  278. </div>
  279. <div class="operation" v-if="auditTypeItem.auditType == 1">
  280. <van-button size="small" type="info"
  281. :to="{ name: 'expenseDetails', params: { id: item.id, canEdit: false, isAudit:true } }">审核</van-button>
  282. </div>
  283. <div class="operation" v-if="auditTypeItem.auditType == 2">
  284. <van-button size="small" type="info" :loading="item.approveLoading"
  285. @click.stop="approve(item)">通过</van-button>
  286. <van-button style="margin-left:15px" size="small" type="danger"
  287. @click.stop="denyToReason(item.id)">驳回</van-button>
  288. </div>
  289. </template>
  290. <div class="wrapper">
  291. <div><span>{{ user.companyId == mechanicalCompanyId ? '工程名称' : '项目名称'}}:</span><span>{{ item.engineeringName }}</span></div>
  292. <div><span>票据编号:</span><span>{{ item.code }}</span></div>
  293. <div><span>金额:</span><span>¥{{ item.totalAmount | numtosum }}</span></div>
  294. <div><span>报销人:</span>
  295. <span v-if="user.userNameNeedTranslate == 1"><TranslationOpenDataText type='userName'
  296. :openid='item.ownerName'></TranslationOpenDataText></span>
  297. <span v-else>{{ item.ownerName }}</span>
  298. </div>
  299. <div><span>填报日期:</span><span>{{ item.createDate }}</span></div>
  300. <div v-if="user.timeType.easyExpense==0 && item.type != '14454'"><span>发票张数:</span><span>{{ item.ticketNum }}</span></div>
  301. <div><span>费用类型:</span><span>{{ item.expenseMainTypeName }}</span></div>
  302. <div>
  303. <span>审核流程:</span>
  304. <span v-if="item.reviewProcess == 0">待第一审核人审核</span>
  305. <span v-if="item.reviewProcess == 1">待第二审核人审核</span>
  306. <span v-if="item.reviewProcess == 2">审核完成</span>
  307. <span v-if="item.reviewProcess == 3">未提交</span>
  308. <span v-if="item.reviewProcess == 4">已驳回</span>
  309. </div>
  310. <!-- <div><span>状态:</span><span>{{item.status}}</span></div> -->
  311. <!-- <div><span>驳回原因:</span><span>{{item.denyReason}}</span></div> -->
  312. <div v-if="item.type == 14454"><span>设备归属人:</span><span>{{ item.equipmentOwnerName }}</span></div>
  313. <div><span>备注:</span><span>{{ item.remark }}</span></div>
  314. </div>
  315. <div class="lookup">
  316. <van-button size="small" type="info"
  317. :to="{ name: 'expenseDetails', params: { id: item.id, canEdit: false } }">查看单据信息</van-button>
  318. </div>
  319. </van-collapse-item>
  320. </van-collapse>
  321. <!-- <van-popup v-model="denyReasonDialog" position="bottom" closeable >
  322. <van-cell>请输入原因</van-cell>
  323. <van-field class="form_input"
  324. v-model="denyParm.denyReason" name="reason" type="textarea" placeholder="请输入您决定驳回的原因"
  325. rows="3" autosize />
  326. <van-button style="width:100%;" type="info" :loading="denyLoading" @click="deny()">提交</van-button>
  327. </van-popup> -->
  328. </div>
  329. </div>
  330. </div>
  331. </template>
  332. <script>
  333. export default {
  334. data() {
  335. return {
  336. auditTypeItem: {auditType: 0},
  337. active: sessionStorage.page ? JSON.parse(sessionStorage.page) : 0,
  338. user: JSON.parse(localStorage.userInfo),
  339. userList: [],
  340. canExamine: false,
  341. currentDate1: new Date(),
  342. currentDate2: new Date(),
  343. minDate: new Date(2020, 0, 1),
  344. maxDate: new Date(2025, 11, 31),
  345. confirmLoading: false,
  346. denyLoading: false,
  347. formshowText: {
  348. name: '',
  349. inProjectName: []
  350. },
  351. // #region 费用报销
  352. editForm: {
  353. ownerId: '',
  354. createDate: this.formatDate(new Date()),
  355. ticketNum: 0,
  356. type: 0,
  357. remark: ''
  358. },
  359. userRadio: null,
  360. ownerIdShow: false,
  361. ownerIdShowType: 1, // 1,报销人, 2第一审核人, 3第二审核人
  362. createDateShow: false,
  363. typeShow: false,
  364. typeList: [],
  365. invoiceIndex: 0,
  366. invoiceList: [
  367. {
  368. projectId: '',
  369. happenDate: '',
  370. invoiceType: '',
  371. expenseType: '',
  372. amount: '',
  373. invoiceNo: '',
  374. taxPercent: '',
  375. taxValue: '',
  376. remark: '',
  377. pic: '',
  378. }
  379. ],
  380. in_projectShow: false,
  381. in_dateShow: false,
  382. in_typeShow: false,
  383. in_exTypeShow: false,
  384. inProjectList: [],
  385. inProjectListCopy: [],
  386. inTypeList: ['增值税专用发票', '增值税普通发票'],
  387. allexTypeList: [],
  388. inexTypeList: [],
  389. uploader: [[]],
  390. // #endregion
  391. // 单据列表
  392. activeName: '',
  393. billList: [],
  394. statusList: ['审核通过', '待审核', '已驳回', '已撤销', '未填写'],
  395. statusClass: ['', 'waiting', 'rejected', '', 'rejected'],
  396. uploading: false,
  397. // 单据审核
  398. auditName: '',
  399. examineList: [],
  400. denyReasonDialog: false,
  401. denyParm: {
  402. id: '',
  403. denyReason: ''
  404. },
  405. expenseMainType: {
  406. text: ''
  407. },
  408. projectSelectVal: '',
  409. firstCheckerText: {},
  410. secondCheckerText: {},
  411. mechanicalCompanyId: 4811,
  412. equipmentOwnerList: [],
  413. equipmentOwner: {},
  414. equipmentOwnershipVisable: false
  415. }
  416. },
  417. computed: {
  418. totalCost() {
  419. let costnum = 0
  420. for (let i in this.invoiceList) {
  421. costnum += (this.invoiceList[i].amount ? parseFloat(this.invoiceList[i].amount) : 0)
  422. }
  423. return costnum.toFixed(2)
  424. }
  425. },
  426. filters: {
  427. numtosum(value) {
  428. if (value == undefined || !value) return '0.00'
  429. value = value.toFixed(2)
  430. const intPart = Math.trunc(value)
  431. const intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
  432. let floatPart = '.00'
  433. const valueArray = value.toString().split('.')
  434. if (valueArray.length === 2) { // 有小数部分
  435. floatPart = valueArray[1].toString() // 取得小数部分
  436. return intPartFormat + '.' + floatPart
  437. }
  438. return intPartFormat + floatPart
  439. },
  440. },
  441. mounted() {
  442. this.formshowText.name = this.user.name;
  443. this.editForm.ownerId = this.user.id;
  444. this.userRadio = {
  445. name: this.user.name,
  446. id: this.user.id
  447. }
  448. this.activeChange()
  449. for (let i in this.user.functionList) {
  450. if (this.user.functionList[i].name == '费用审核') {
  451. this.canExamine = true
  452. }
  453. }
  454. if (!this.canExamine) {
  455. this.editForm.ownerId = this.user.id
  456. this.formshowText.name = this.user.name
  457. }
  458. this.getUserList()
  459. this.getProjectList()
  460. this.getExpensMainTypes()
  461. this.getExTypeList()
  462. this.getAuditType();
  463. if(this.user.companyId == this.mechanicalCompanyId) {
  464. this.getEquipmentOwnerList()
  465. }
  466. },
  467. methods: {
  468. // 项目搜索
  469. projectSelect() {
  470. if(this.projectSelectVal.length > 0) {
  471. let data = this.inProjectListCopy.filter(item => {return item.projectName && item.projectName.includes(this.projectSelectVal)});
  472. let dataList = this.inProjectListCopy.filter(item => {return item.projectCode && item.projectCode.includes(this.projectSelectVal)});
  473. let dataTree = data.concat(dataList)
  474. let arrList = Array.from(new Set(dataTree))
  475. this.inProjectList = arrList
  476. } else {
  477. this.inProjectList = JSON.parse(JSON.stringify(this.inProjectListCopy))
  478. }
  479. },
  480. back() {
  481. sessionStorage.removeItem("page");
  482. history.back();
  483. },
  484. formatDate(date) {
  485. let mon = date.getMonth() + 1
  486. return `${date.getFullYear()}-${mon < 10 ? '0' + mon : mon}-${date.getDate() < 10 ? '0' + date.getDate() : date.getDate()}`;
  487. },
  488. getTaxValue(amount, percent) {
  489. let per = percent / 100
  490. let amo = amount / (1 + per) * per
  491. return amo.toFixed(2)
  492. },
  493. activeChange() {
  494. sessionStorage.setItem('page', JSON.stringify(this.active))
  495. if (this.active == 1) {
  496. this.getBillList()
  497. }
  498. if (this.active == 2) {
  499. this.getExamineList()
  500. }
  501. },
  502. // #region 费用报销
  503. ownerIdChange() {
  504. if(this.ownerIdShowType == 1) {
  505. this.editForm.ownerId = this.userRadio.id
  506. this.formshowText.name = this.userRadio.name
  507. } else if(this.ownerIdShowType == 2) {
  508. this.$set(this.firstCheckerText, 'id', this.userRadio.id)
  509. this.$set(this.firstCheckerText, 'name', this.userRadio.name)
  510. } else if(this.ownerIdShowType == 3) {
  511. this.$set(this.secondCheckerText, 'id', this.userRadio.id)
  512. this.$set(this.secondCheckerText, 'name', this.userRadio.name)
  513. }
  514. this.ownerIdShow = false
  515. },
  516. createDateChange(value, key) {
  517. this.editForm.createDate = this.formatDate(value)
  518. this.createDateShow = false
  519. },
  520. typeChange(value, key) {
  521. this.separateProcessingAndJudgment(value)
  522. this.editForm.type = value.id
  523. this.expenseMainType.text = value.name
  524. this.typeShow = false
  525. for (let i in this.invoiceList) {
  526. this.invoiceList[i].expenseType = ''
  527. }
  528. this.inexTypeList = this.allexTypeList.filter(a => a.mainType == this.editForm.type)
  529. },
  530. deviceTypeChange(value) {
  531. console.log(value)
  532. this.equipmentOwner = value
  533. this.equipmentOwnershipVisable = false
  534. },
  535. separateProcessingAndJudgment(value) {
  536. if(this.user.companyId == this.mechanicalCompanyId) {
  537. if(value.id == '14454') {
  538. this.userList = JSON.parse(JSON.stringify(this.userList)).filter(item => item.id != this.user.id)
  539. const obj = { id: '', name: '' }
  540. this.firstCheckerText = obj
  541. this.secondCheckerText = obj
  542. if(this.editForm.ownerId == this.user.id) {
  543. this.editForm.ownerId = ''
  544. this.formshowText.name = ''
  545. }
  546. } else {
  547. this.editForm.ownerId = this.user.id
  548. this.formshowText.name = this.user.name
  549. this.userList = JSON.parse(JSON.stringify(this.userList))
  550. }
  551. }
  552. },
  553. ticNumChange(value) {
  554. if (value) {
  555. this.invoiceList.push({
  556. projectId: '',
  557. happenDate: '',
  558. invoiceType: '',
  559. expenseType: '',
  560. amount: '',
  561. invoiceNo: '',
  562. taxPercent: '',
  563. taxValue: '',
  564. remark: '',
  565. pic: '',
  566. })
  567. } else {
  568. this.invoiceList.pop()
  569. }
  570. },
  571. // 发票
  572. inProjectChange(value, key) {
  573. this.formshowText.inProjectName[this.invoiceIndex] = value.projectName
  574. this.invoiceList[this.invoiceIndex].projectId = value.id
  575. this.in_projectShow = false
  576. },
  577. inDateChange(value, key) {
  578. this.invoiceList[this.invoiceIndex].happenDate = this.formatDate(value)
  579. this.in_dateShow = false
  580. },
  581. inTypeChange(value, key) {
  582. this.invoiceList[this.invoiceIndex].invoiceType = key
  583. this.in_typeShow = false
  584. },
  585. inexTypeChange(value, key) {
  586. this.invoiceList[this.invoiceIndex].expenseType = value.typeName
  587. this.in_exTypeShow = false
  588. },
  589. addInvoice() {
  590. this.invoiceList.push({
  591. projectId: '',
  592. happenDate: '',
  593. invoiceType: '',
  594. expenseType: '',
  595. amount: '',
  596. invoiceNo: '',
  597. taxPercent: '',
  598. taxValue: '',
  599. remark: '',
  600. pic: '',
  601. })
  602. this.uploader.push([])
  603. this.editForm.ticketNum = this.invoiceList.length
  604. },
  605. deleteInvoice(index) {
  606. this.invoiceList.splice(index, 1)
  607. this.uploader.splice(index, 1)
  608. this.editForm.ticketNum = this.invoiceList.length
  609. },
  610. // 上传报销凭证
  611. beforeRead(file) {
  612. // console.log(file, file.length)
  613. // console.log(Array.isArray(file))
  614. // if (file.type != 'image/jpeg' && file.type != 'image/png' && file.type != 'image/jpg') {
  615. // this.$toast.fail('请选择jpg或png格式的图片')
  616. // return false
  617. // }
  618. // return true
  619. let newFile = Array.isArray(file) ? file : [file]
  620. for(var i in newFile) {
  621. const fileItem = newFile[i]
  622. if (fileItem.type != 'image/jpeg' && fileItem.type != 'image/png' && fileItem.type != 'image/jpg') {
  623. this.$toast.fail('请选择jpg或png格式的图片')
  624. return false
  625. }
  626. }
  627. return true
  628. },
  629. afterRead(file) {
  630. // let formData = new FormData();
  631. // formData.append("multipartFile", file.file);
  632. // this.$axios.post("/common/uploadFile", formData)
  633. // .then(res => {
  634. // if (res.code == "ok") {
  635. // this.invoiceList[this.invoiceIndex].pic = res.data
  636. // } else {
  637. // this.$toast.fail('上传失败');
  638. // this.uploader[this.invoiceIndex] = []
  639. // }
  640. // }).catch(err => { this.$toast.clear(); console.log(err); this.uploader[this.invoiceIndex] = [] });
  641. let newFile = Array.isArray(file) ? file : [file]
  642. let formData = new FormData();
  643. for(var i in newFile) {
  644. formData.append("multipartFiles", newFile[i].file);
  645. }
  646. this.$axios.post("/common/uploadFileArray", formData)
  647. .then(res => {
  648. if (res.code == "ok") {
  649. let newPic = this.invoiceList[this.invoiceIndex].pic || []
  650. let newData = res.data.split(';')
  651. this.invoiceList[this.invoiceIndex].pic = [...newPic, ...newData]
  652. console.log(this.invoiceList[this.invoiceIndex].pic, '<=== 合计图片')
  653. } else {
  654. this.$toast.fail('上传失败');
  655. this.uploader[this.invoiceIndex] = []
  656. }
  657. }).catch(err => { this.$toast.clear(); console.log(err); this.uploader[this.invoiceIndex] = [] });
  658. },
  659. // 删除图片
  660. deteleImg(file, item, arrIndex) {
  661. let index = item.index
  662. this.invoiceList[arrIndex].pic = this.invoiceList[arrIndex].pic.filter((item,i) => i != index)
  663. },
  664. // 提交
  665. submitExpense() {
  666. if (!this.editForm.ownerId) {
  667. this.$toast.fail('请选择报销人')
  668. return
  669. }
  670. if (!this.editForm.createDate) {
  671. this.$toast.fail('请选择填报日期')
  672. return
  673. }
  674. if(this.auditTypeItem.auditType == 2 && this.editForm.type != 14454) {
  675. if(!this.firstCheckerText.id || !this.secondCheckerText.id) {
  676. this.$toast.fail(`${!this.firstCheckerText.id ? '请选择第一审核人' : '请选择第二审核人'}`)
  677. return
  678. } else {
  679. this.editForm.firstCheckerId = this.firstCheckerText.id
  680. this.editForm.secondCheckerId = this.secondCheckerText.id
  681. }
  682. }
  683. let required1 = false
  684. let required2 = false
  685. let required3 = false
  686. let required4 = false
  687. let required5 = false
  688. for (let i in this.invoiceList) {
  689. if (!this.invoiceList[i].projectId) {
  690. required1 = '所属项目'
  691. }
  692. if (!this.invoiceList[i].happenDate) {
  693. required2 = '费用日期'
  694. }
  695. // if (!this.invoiceList[i].invoiceType) {
  696. // required3 = '发票种类'
  697. // }
  698. if (!this.invoiceList[i].expenseType) {
  699. required4 = '费用类型'
  700. }
  701. if (!this.invoiceList[i].amount) {
  702. if(this.user.companyId != this.mechanicalCompanyId && this.editForm.type != 14454 && this.user.id != this.editForm.ownerId) {
  703. required5 = this.user.timeType.easyExpense==0?'费用金额(含税)':'费用金额'
  704. }
  705. }
  706. }
  707. if (required1 || required2 || required3 || required4 || required5) {
  708. let requiredStr = (required1 ? required1 + '、' : '')
  709. + (required2 ? required2 + '、' : '')
  710. + (required3 ? required3 + '、' : '')
  711. + (required4 ? required4 + '、' : '')
  712. + (required5 ? required5 + '、' : '')
  713. requiredStr = requiredStr.substring(0, requiredStr.length - 1)
  714. this.$toast.fail('请添加发票的[' + requiredStr + ']')
  715. return
  716. }
  717. if (this.invoiceList.length == 0) {
  718. this.$toast.fail('请添加发票')
  719. return
  720. }
  721. for (let i in this.invoiceList) {
  722. this.invoiceList[i].taxValue = this.getTaxValue(this.invoiceList[i].amount, this.invoiceList[i].taxPercent)
  723. }
  724. let newList = JSON.parse(JSON.stringify(this.invoiceList))
  725. for(let i in newList) {
  726. if(newList[i].pic) {
  727. newList[i].pic = newList[i].pic.join(',')
  728. }
  729. }
  730. // this.editForm.items = JSON.stringify(this.invoiceList)
  731. this.editForm.items = JSON.stringify(newList)
  732. this.editForm.totalAmount = this.totalCost
  733. if(this.equipmentOwner.id) {
  734. this.editForm.equipmentOwnerId = this.equipmentOwner.id
  735. }
  736. // 获取新的票据编号
  737. this.confirmLoading = true
  738. this.$axios.post("/expense-sheet/getNextCode", {})
  739. .then(res => {
  740. if (res.code == "ok") {
  741. this.editForm.code = res.data
  742. // 提交
  743. this.$axios.post("/expense-sheet/add", this.editForm)
  744. .then(res => {
  745. this.confirmLoading = false;
  746. if (res.code == "ok") {
  747. this.$toast.success('填报成功')
  748. this.editForm = {
  749. ownerId: '',
  750. createDate: this.formatDate(new Date()),
  751. ticketNum: 0,
  752. type: 0,
  753. remark: ''
  754. }
  755. // this.formshowText = {
  756. // name: '',
  757. // inProjectName: []
  758. // }
  759. this.$set(this, 'firstCheckerText', {})
  760. this.$set(this, 'secondCheckerText', {})
  761. this.formshowText.name = ''
  762. this.formshowText.inProjectName = []
  763. this.expenseMainType.text=''
  764. this.invoiceList = []
  765. this.uploader = []
  766. this.formshowText.name = this.user.name;
  767. this.editForm.ownerId = this.user.id;
  768. this.userRadio = {
  769. name: this.user.name,
  770. id: this.user.id
  771. }
  772. } else {
  773. this.$toast.fail(res.msg || res.code || '填报失败');
  774. }
  775. }).catch(err => { this.confirmLoading = false; this.$toast.clear(); console.log(err) });
  776. } else {
  777. this.confirmLoading = false
  778. this.$toast.fail('获取失败');
  779. }
  780. }).catch(err => {
  781. this.confirmLoading = false;
  782. this.$toast.clear();
  783. console.log(err)
  784. });
  785. },
  786. // #endregion
  787. // 单据列表
  788. deleteBill(pid) {
  789. this.$dialog.confirm({
  790. message: '确认删除?',
  791. })
  792. .then(() => {
  793. // on confirm
  794. this.$axios.post("/expense-sheet/delete", { id: pid })
  795. .then(res => {
  796. if (res.code == "ok") {
  797. this.$toast.success('删除成功')
  798. this.getBillList()
  799. } else {
  800. this.$toast.fail(res.msg || res.code || '删除失败');
  801. }
  802. }).catch(err => { this.$toast.clear(); console.log(err) });
  803. })
  804. .catch(() => {
  805. // on cancel
  806. });
  807. },
  808. getAuditType() {
  809. this.$axios.post("/expense-audit-setting/get", {})
  810. .then(res => {
  811. if (res.code == "ok") {
  812. this.auditTypeItem = res.data;
  813. } else {
  814. this.$message({
  815. message: res.msg,
  816. type: "error"
  817. });
  818. }
  819. }).catch(err => { this.$toast.clear(); console.log(err) });
  820. },
  821. // 单据审核
  822. approve(item) {
  823. item.approveLoading = true
  824. this.$axios.post("/expense-sheet/approve", { id: item.id })
  825. .then(res => {
  826. if (res.code == "ok") {
  827. this.$toast.success('已通过')
  828. item.approveLoading = false
  829. this.getExamineList()
  830. } else {
  831. this.$toast.fail('操作失败');
  832. }
  833. }).catch(err => { this.$toast.clear(); console.log(err) });
  834. },
  835. denyToReason(pid) {
  836. this.denyParm.id = pid
  837. this.denyReasonDialog = true
  838. this.denyParm.denyReason = ''
  839. this.deny()
  840. },
  841. deny() {
  842. this.denyLoading = true
  843. this.$axios.post("/expense-sheet/deny", this.denyParm)
  844. .then(res => {
  845. if (res.code == "ok") {
  846. this.$toast.success('已驳回')
  847. this.denyReasonDialog = false
  848. this.denyLoading = false
  849. this.getExamineList()
  850. } else {
  851. this.$toast.fail(res.msg || res.code || '操作失败');
  852. }
  853. }).catch(err => { this.$toast.clear(); console.log(err) });
  854. },
  855. getUserList() {
  856. this.$axios.post("/user/getSimpleActiveUserList", {})
  857. .then(res => {
  858. if (res.code == "ok") {
  859. this.userList = res.data
  860. this.copyUserList = JSON.parse(JSON.stringify(res.data))
  861. } else {
  862. this.$toast.fail(res.msg || res.code || '获取失败');
  863. }
  864. }).catch(err => { this.$toast.clear(); console.log(err) });
  865. },
  866. getProjectList() {
  867. this.$axios.post("/project/getProjectList", {})
  868. .then(res => {
  869. if (res.code == "ok") {
  870. this.inProjectList = res.data
  871. this.inProjectListCopy = JSON.parse(JSON.stringify(res.data))
  872. } else {
  873. this.$toast.fail(res.msg || res.code || '获取失败');
  874. }
  875. }).catch(err => { this.$toast.clear(); console.log(err) });
  876. },
  877. getExTypeList() {
  878. this.$axios.post("/expense-type/getList", {})
  879. .then(res => {
  880. if (res.code == "ok") {
  881. this.allexTypeList = res.data
  882. this.inexTypeList = this.allexTypeList.filter(a => a.mainType == this.editForm.type)
  883. } else {
  884. this.$toast.fail(res.msg || res.code || '获取失败');
  885. }
  886. }).catch(err => { this.$toast.clear(); console.log(err) });
  887. },
  888. getExpensMainTypes() {
  889. this.$axios.post("/expense-main-type/list", {})
  890. .then(res => {
  891. if (res.code == "ok") {
  892. for (var i in res.data) {
  893. res.data[i].text = res.data[i].name
  894. }
  895. if(this.user.isMachineCost != 2) {
  896. this.typeList = res.data.filter(item => item.id != 14454)
  897. } else {
  898. this.typeList = res.data
  899. }
  900. this.expenseMainType.text = res.data[0].name
  901. this.editForm.type = res.data[0].id
  902. this.getExTypeList
  903. } else {
  904. this.$toast.fail(res.msg || res.code || '获取失败');
  905. }
  906. }).catch(err => { this.$toast.clear(); console.log(err) });
  907. },
  908. getEquipmentOwnerList() {
  909. this.$axios.post("/equipment-owner/getList", {})
  910. .then(res => {
  911. if (res.code == "ok") {
  912. this.equipmentOwnerList = (res.data || []).map(item => {
  913. return {
  914. name: item.equipmentOwner,
  915. id: item.id,
  916. text: item.equipmentOwner
  917. };
  918. });
  919. } else {
  920. this.$toast.fail(res.msg || res.code || '获取失败');
  921. }
  922. }).catch(err => { this.$toast.clear(); console.log(err) });
  923. },
  924. getBillList() {
  925. this.$axios.post("/expense-sheet/list", {
  926. pageSize: 999,
  927. pageIndex: 1,
  928. startDate: '',
  929. endDate: '',
  930. ownerId: '',
  931. type: ''
  932. }).then(res => {
  933. if (res.code == "ok") {
  934. this.billList = res.data.records
  935. } else {
  936. this.$toast.fail(res.msg || res.code || '获取失败');
  937. }
  938. }).catch(err => { this.$toast.clear(); console.log(err) });
  939. },
  940. getExamineList() {
  941. this.$axios.post("/expense-sheet/list", {
  942. pageSize: 999,
  943. pageIndex: 1,
  944. startDate: '',
  945. endDate: '',
  946. ownerId: '',
  947. type: '',
  948. status: 1
  949. }).then(res => {
  950. if (res.code == "ok") {
  951. this.examineList = res.data.records
  952. for (let i in this.examineList) {
  953. this.$set(this.examineList[i], 'approveLoading', false)
  954. }
  955. } else {
  956. this.$toast.fail(res.msg || res.code || '获取失败');
  957. }
  958. }).catch(err => { this.$toast.clear(); console.log(err) });
  959. },
  960. ownerIdShowCli(type) {
  961. if(type > 1 && this.editForm.type == '14454') return
  962. if(type > 1) {
  963. this.canExamine = true
  964. }
  965. if(this.user.isMachineCost > 1 && this.editForm.type == '14454') {
  966. this.canExamine = true
  967. }
  968. this.ownerIdShowType = type
  969. this.userRadio = ''
  970. this.ownerIdShow = true
  971. }
  972. },
  973. }
  974. </script>
  975. <style lang="less" scoped>
  976. .content {
  977. margin-top: 46px;
  978. overflow: auto;
  979. .edit {
  980. .userCheckbox {
  981. padding: 10px;
  982. }
  983. padding-bottom: 46px;
  984. .form_btn {
  985. z-index: 1000;
  986. }
  987. .edit_form {
  988. .invoice {
  989. border: 0.5px solid rgb(135, 195, 255);
  990. margin: 0.2rem;
  991. .deletebtn {
  992. position: absolute;
  993. z-index: 900;
  994. font-size: 24px;
  995. right: 0.08rem;
  996. top: 0.08rem;
  997. color: #c03131;
  998. }
  999. .invoice_item {
  1000. border-top: 0.5px solid rgb(135, 195, 255);
  1001. }
  1002. }
  1003. .addinvoice {
  1004. padding: 0 0.3rem 0.3rem;
  1005. margin-top: 0.2rem;
  1006. text-align: right;
  1007. }
  1008. }
  1009. .imgListVan {
  1010. display: flex;
  1011. flex-direction: column;
  1012. }
  1013. .vanUploaderImg {
  1014. // display: flex;
  1015. margin-top: 6px;
  1016. /deep/ .van-uploader__preview-image {
  1017. width: 70px;
  1018. height: 70px;
  1019. }
  1020. }
  1021. /deep/ .van-uploader__upload {
  1022. width: 70px;
  1023. height: 70px;
  1024. }
  1025. }
  1026. .list {
  1027. .list_collapse>div {
  1028. margin: 4px;
  1029. }
  1030. .list_collapse {
  1031. .collapse_label_l {
  1032. width: 50%;
  1033. padding: 4px;
  1034. display: inline-block;
  1035. }
  1036. .collapse_label_r {
  1037. width: 50%;
  1038. padding: 4px;
  1039. display: inline-block;
  1040. .waiting {
  1041. color: orange;
  1042. }
  1043. .rejected {
  1044. color: red;
  1045. }
  1046. }
  1047. .wrapper {
  1048. div {
  1049. margin: 8px 16px;
  1050. }
  1051. div span:nth-child(1) {
  1052. width: 30%;
  1053. display: inline-block;
  1054. }
  1055. div span:nth-child(2) {
  1056. width: 70%;
  1057. display: inline-block;
  1058. }
  1059. }
  1060. .operation {
  1061. display: flex;
  1062. align-items: center;
  1063. justify-content: flex-end;
  1064. }
  1065. }
  1066. }
  1067. .audit {
  1068. .list_collapse>div {
  1069. margin: 4px;
  1070. }
  1071. .list_collapse {
  1072. .collapse_label_l {
  1073. width: 60%;
  1074. padding: 4px;
  1075. display: inline-block;
  1076. }
  1077. .collapse_label_r {
  1078. width: 40%;
  1079. padding: 4px;
  1080. display: inline-block;
  1081. .waiting {
  1082. color: orange;
  1083. }
  1084. .rejected {
  1085. color: red;
  1086. }
  1087. }
  1088. .operation {
  1089. margin-top: 5px;
  1090. padding-top: 5px;
  1091. border-top: 0.5px solid #ebedf0;
  1092. display: flex;
  1093. align-items: center;
  1094. justify-content: flex-end;
  1095. button {
  1096. width: 1.2rem;
  1097. }
  1098. }
  1099. .wrapper {
  1100. div {
  1101. margin: 8px 16px;
  1102. }
  1103. div span:nth-child(1) {
  1104. width: 30%;
  1105. display: inline-block;
  1106. }
  1107. div span:nth-child(2) {
  1108. width: 70%;
  1109. display: inline-block;
  1110. }
  1111. }
  1112. .lookup {
  1113. display: flex;
  1114. align-items: center;
  1115. justify-content: flex-end;
  1116. }
  1117. }
  1118. }
  1119. }
  1120. </style>
  1121. <style>
  1122. .edit_form .invoice .van-field__label {
  1123. color: #999;
  1124. }
  1125. .edit_form .invoice .van-field__control {
  1126. color: #999;
  1127. }
  1128. </style>