sample-collection.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. <template>
  2. <view class="container">
  3. <view class="header">
  4. <view class="segmented-control-item" :class="{ 'active': activeTab === 0 }" @click="switchTab(0)">接待信息
  5. <view class="underline" v-show="activeTab === 0"></view>
  6. </view>
  7. <view class="segmented-control-item" :class="{ 'active': activeTab === 1 }" @click="switchTab(1)">选样扫描
  8. <view class="underline" v-show="activeTab === 1"></view>
  9. </view>
  10. <view class="segmented-control-item" :class="{ 'active': activeTab === 2 }" @click="switchTab(2)">选样列表
  11. <view class="underline" v-show="activeTab === 2"></view>
  12. </view>
  13. </view>
  14. <!-- <view class="absolute-element"> -->
  15. <scroll-view class="scroll-view" scroll-y="true">
  16. <!-- 根据 activeTab 显示不同的页面 -->
  17. <!-- <view v-if="activeTab === 0"> -->
  18. <view class="content" v-if="activeTab === 0">
  19. <u--form labelPosition="left" v-model="baseData" ref="uForm" labelWidth='40'>
  20. <u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click="" ref="uItem">
  21. <u--input v-model.trim="baseData.exhibitionName" placeholder="请输入展会名称" border="none"></u--input>
  22. </u-form-item><u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click=""
  23. ref="uItem">
  24. <u--input v-model.trim="baseData.customerName" placeholder="请输入客户名称" border="none"></u--input>
  25. </u-form-item><u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click=""
  26. ref="uItem">
  27. <u--input v-model.trim="baseData.receiver" placeholder="请输入接待人姓名" border="none"></u--input>
  28. </u-form-item><u-form-item prop="" borderBottom @click="" ref="uItem">
  29. <u--textarea v-model="baseData.exhibitionNote" placeholder="展会备注信息"></u--textarea>
  30. </u-form-item>
  31. <uni-section title="添加图片" type="line" required>
  32. <uni-file-picker :value="baseData.fileList" :source-type="['album', 'camera']"
  33. @select="handleFileSelect" @delete="handleDelete" ref="filePicker">
  34. </uni-file-picker>
  35. </uni-section>
  36. <u-button style="margin-top: 5px;" @click="handleSave" type="primary" color="#253a6f"
  37. text="保存接待信息"></u-button>
  38. </u--form>
  39. </view>
  40. <view class="content" v-if="activeTab === 1">
  41. <u--form labelPosition="left" v-model="detailData" ref="uForm" labelWidth='40'>
  42. <u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click="" ref="uItem">
  43. <u--input readonly v-model.trim="detailData.customerName" placeholder=""
  44. border="none"></u--input>
  45. </u-form-item><u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click=""
  46. ref="uItem">
  47. <u--input type="text" v-model.trim="detailData.barCode" @confirm="getScanValue" :focus="focus"
  48. placeholder="样品条码序列号" border="none"></u--input>
  49. </u-form-item>
  50. <u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click="" ref="uItem">
  51. <u--input type="text" v-model.trim="detailData.barCode" @confirm="getScanValue" :focus="focus"
  52. placeholder="样品条码序列号" border="none"></u--input>
  53. <u-button slot="right" type="primary" hairline size="small" @click="scan()">扫描条码</u-button>
  54. </u-form-item>
  55. <u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click="" ref="uItem">
  56. <u--input type="number" v-model.trim="detailData.bpQuantity" placeholder="布片数量(默认为1)"
  57. border="none"></u--input>
  58. </u-form-item><u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click=""
  59. ref="uItem">
  60. <u--input type="number" v-model.trim="detailData.gyQuantity" placeholder="挂样数量(默认为0)"
  61. border="none"></u--input>
  62. </u-form-item><u-form-item left-icon="../../static/logo.png" prop="" borderBottom @click=""
  63. ref="uItem">
  64. <u--input type="number" v-model.trim="detailData.myQuantity" placeholder="米样数量(默认为0)"
  65. border="none"></u--input>
  66. </u-form-item><u-form-item prop="" borderBottom @click="" ref="uItem">
  67. <u--textarea v-model="detailData.note" placeholder="样品备注信息"></u--textarea>
  68. </u-form-item>
  69. <uni-section title="添加图片" type="line" required>
  70. <uni-file-picker :value="detailData.fileList" :source-type="['album', 'camera']"
  71. @select="handleDetailFileSelect" @delete="handleDelete" ref="filePicker">
  72. </uni-file-picker>
  73. </uni-section>
  74. <u-button style="margin-top: 5px;" @click="handleSaveDetail" type="primary" color="#253a6f"
  75. text="保存选样"></u-button>
  76. </u--form>
  77. </view>
  78. <view v-if="activeTab === 2">
  79. <u-swipe-action>
  80. <u-swipe-action-item v-for="(item, index) in indexList" :options="options" @click="showDetail"
  81. :index="index" :key="index" :name="index">
  82. <view class="swipe-action u-border-top"
  83. :class="[index === indexList.length - 1 && 'u-border-bottom']">
  84. <view class="swipe-action__content" :style="item.msg ? 'background-color:red' : ''">
  85. <text class="swipe-action__content__text">包装号:{{ item.PackNO }}</text>
  86. </view>
  87. </view>
  88. </u-swipe-action-item>
  89. </u-swipe-action>
  90. <view class="card-bottom" style="">
  91. <view style="font-size: 14px;">
  92. <view>
  93. <uni-forms-item label="出货口" label-width="80px" required name="WarehouseGuid"
  94. style="padding: 0;margin: 0;">
  95. <uni-data-picker v-model="OutWarehousePort" :localdata="outWarehousePortList"
  96. @change="">
  97. </uni-data-picker>
  98. </uni-forms-item>
  99. </view>
  100. <view style="display: flex;">
  101. <button style="width: 100%;" type="primary" @click="delivery">准备出库</button>
  102. <button style="width:100%;" type="default" @click="queue">出库排队</button>
  103. </view>
  104. <!-- <button class="mini-btn" type="warn" size="mini" @click="cancelstorage" v-if="BillNO != null">入库</button> -->
  105. <!-- <button class="mini-btn" type="warn" size="mini">返回</button> -->
  106. </view>
  107. </view>
  108. </view>
  109. </scroll-view>
  110. </view>
  111. </template>
  112. <script>
  113. import {
  114. openSqlite,
  115. executeSql,
  116. closedb,
  117. getTable,
  118. isTable,
  119. getAllField,
  120. insertAll,
  121. addSql,
  122. getPageList,
  123. selectList,
  124. deleteSql,
  125. updateSql,
  126. selectSql,
  127. batchUpdate
  128. } from "@/utils/database";
  129. export default {
  130. data() {
  131. return {
  132. tableName: "public",
  133. baseData: {},
  134. detailData: {
  135. barCode: '',
  136. bpQuantity: '',
  137. gyQuantity: '',
  138. myQuantity: '',
  139. note: "",
  140. fileList: [],
  141. },
  142. customStyle: {
  143. // marginTop: '20px', // 注意驼峰命名,并且值必须用引号包括,因为这是对象
  144. // color: 'red',
  145. border: '1px solid black'
  146. },
  147. focus: true,
  148. // baseData: {
  149. // exhibitionName: '',
  150. // customerName: '',
  151. // receiver: '',
  152. // exhibitionNote: "",
  153. // fileList: [],
  154. // },
  155. activeTab: 0, // 当前选中的页面索引
  156. imageUrl: 'file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/uniapp_save/17049440506630.jpg',
  157. fileSavePath: []
  158. };
  159. },
  160. async onShow() {
  161. /**
  162. * 数据库设置名称 在 database.js 文件中
  163. */
  164. // console.log("所有表名称",await getTable())
  165. // 默认打开数据库,并创建表
  166. await this.openSqlite()
  167. await this.createTable()
  168. await this.createDetailTable()
  169. },
  170. computed: {
  171. },
  172. //获取上一页传过来的参数
  173. onLoad(option) {
  174. console.log(option.data)
  175. this.baseData = JSON.parse(decodeURIComponent(option.data));
  176. console.log(this.baseData.fileList)
  177. const dbPath = plus.io.convertLocalFileSystemURL('_doc/sample_storage.db');
  178. console.log(dbPath); // 输出类似"/storage/emulated/0/Android/data/com.example.myapp/files/database/test.db"的路径
  179. },
  180. methods: {
  181. getScanValue(event) {
  182. setTimeout(() => {
  183. console.log(this.detailData.barCode)
  184. // console.log(event)
  185. this.handleSaveDetail1()
  186. }, 500)
  187. // this.handleSaveDetail()
  188. // this.pointblur();
  189. // console.log('hahahha')
  190. },
  191. pointblur() {
  192. this.focus = false
  193. this.$nextTick(() => {
  194. this.focus = true
  195. })
  196. },
  197. //扫描设备二维码
  198. scan() {
  199. uni.scanCode({
  200. scanType: ['CODE_128'],
  201. success: qrcode => {
  202. let scanRedult = qrcode.result
  203. console.log(qrcode)
  204. // if (scanRedult.indexOf('/')>0) {
  205. // const scanResultArray = scanRedult.split('/')
  206. // let code = scanResultArray[1]
  207. // if(code.indexOf(':')>0){
  208. // code = code.substr(code.indexOf(':')+1)
  209. // }
  210. // this.model1.bill.equipmentCode = code
  211. // }else{
  212. // this.model1.bill.equipmentCode = scanRedult
  213. // }
  214. // if (this.isVerified) {
  215. // this.getEquipmentInfo()
  216. // }
  217. }
  218. })
  219. },
  220. handleFileSelect(e) {
  221. console.log(e.tempFiles)
  222. const self = this
  223. this.handleSaveImages(e) //上传图片
  224. .then(e => {
  225. console.log('returneeeee', e);
  226. self.baseData.fileList = self.baseData.fileList.concat(e.tempFiles)
  227. console.log('fileList', self.baseData.fileList)
  228. })
  229. },
  230. handleDetailFileSelect(e) {
  231. console.log(e.tempFiles)
  232. const self = this
  233. this.handleSaveImages(e) //上传图片
  234. .then(e => {
  235. console.log('returneeeee', e);
  236. self.detailData.fileList = self.detailData.fileList.concat(e.tempFiles)
  237. console.log('fileList', self.detailData.fileList)
  238. })
  239. },
  240. async handleSaveImages(e) {
  241. console.log('eeee', e)
  242. for (const item of e.tempFiles) {
  243. console.log('bbbb', item)
  244. try {
  245. const trueurl = await this.saveImage(item.path);
  246. item.url = trueurl;
  247. console.log('item', item)
  248. } catch (error) {
  249. console.error(`Failed to convert image to Base64:`, error);
  250. }
  251. }
  252. return e
  253. },
  254. // 定义一个异步函数上传图片
  255. async saveImage(filePath) {
  256. console.log(filePath)
  257. return new Promise((resolve, reject) => {
  258. uni.saveFile({
  259. tempFilePath: filePath,
  260. success: res => {
  261. console.log('文件保存成功', res);
  262. resolve(res.savedFilePath);
  263. },
  264. fail: err => reject(err)
  265. })
  266. });
  267. },
  268. handleDelete(e) {
  269. console.log(e)
  270. // uni.removeSavedFile({
  271. // filePath: res.fileList[0].filePath,
  272. // complete: function(res) {
  273. // console.log(res);
  274. // }
  275. // });
  276. this.baseData.fileList = this.baseData.fileList.filter(item => item !== e.tempFile)
  277. },
  278. async handleSave() {
  279. // 修改数据
  280. // baseData: {
  281. // exhibitionName: '',
  282. // customerName: '',
  283. // receiver: '',
  284. // exhibitionNote: "",
  285. // fileList: [],
  286. // },
  287. const urls = this.baseData.fileList.map(item => item.url);
  288. // 使用 join 方法将剩余元素以逗号拼接为字符串
  289. const fileSavePath = urls.join(', ');
  290. console.log(fileSavePath);
  291. try {
  292. await updateSql(this.tableName, {
  293. exhibitionName: this.baseData.exhibitionName,
  294. customerName: this.baseData.customerName,
  295. receiver: this.baseData.receiver,
  296. exhibitionNote: this.baseData.exhibitionNote,
  297. fileSavePath: fileSavePath
  298. }, {
  299. uid: this.baseData.uid
  300. })
  301. const self = this
  302. uni.showToast({
  303. title: "修改成功",
  304. icon: "none",
  305. success: function() {
  306. self.detailData.customerName = self.baseData.customerName
  307. // showToast 弹窗关闭后执行跳转
  308. self.switchTab(1)
  309. }
  310. });
  311. } catch (e) {
  312. uni.showToast({
  313. title: "修改报错,请查看控制台",
  314. icon: "none"
  315. });
  316. console.error("修改报错", e)
  317. }
  318. },
  319. async handleSaveDetail1() {
  320. // 使用 map 方法提取需要的属性值
  321. const urls = this.detailData.fileList.map(item => item.url);
  322. // 使用 join 方法将剩余元素以逗号拼接为字符串
  323. const fileSavePath = urls.join(', ');
  324. console.log(fileSavePath); // 输出 "Alice, Charlie"
  325. try {
  326. // detailData: {
  327. // barCode: '',
  328. // bpQuantity: '',
  329. // gyQuantity: '',
  330. // myQuantity: '',
  331. // note: "",
  332. // fileList: [],
  333. // },
  334. let b = await addSql('detail', {
  335. publicId: this.baseData.uid,
  336. barCode: this.detailData.barCode,
  337. bpQuantity: this.detailData.bpQuantity || 1,
  338. gyQuantity: this.detailData.gyQuantity || 0,
  339. myQuantity: this.detailData.myQuantity || 0,
  340. note: this.detailData.note,
  341. fileSavePath: fileSavePath
  342. })
  343. const self = this
  344. uni.showToast({
  345. title: "添加成功",
  346. icon: "none",
  347. success: function() {
  348. self.detailData.barCode = ''
  349. self.pointblur()
  350. // showToast 弹窗关闭后执行跳转
  351. self.switchTab(1)
  352. }
  353. });
  354. } catch (e) {
  355. console.error("添加数据,报错", e)
  356. }
  357. },
  358. async handleSaveDetail() {
  359. // 使用 map 方法提取需要的属性值
  360. const urls = this.detailData.fileList.map(item => item.url);
  361. // 使用 join 方法将剩余元素以逗号拼接为字符串
  362. const fileSavePath = urls.join(', ');
  363. console.log(fileSavePath); // 输出 "Alice, Charlie"
  364. try {
  365. // detailData: {
  366. // barCode: '',
  367. // bpQuantity: '',
  368. // gyQuantity: '',
  369. // myQuantity: '',
  370. // note: "",
  371. // fileList: [],
  372. // },
  373. let b = await addSql('detail', {
  374. publicId: this.baseData.uid,
  375. barCode: this.detailData.barCode,
  376. bpQuantity: this.detailData.bpQuantity || 1,
  377. gyQuantity: this.detailData.gyQuantity || 0,
  378. myQuantity: this.detailData.myQuantity || 0,
  379. note: this.detailData.note,
  380. fileSavePath: fileSavePath
  381. })
  382. const self = this
  383. uni.showToast({
  384. title: "添加成功",
  385. icon: "none",
  386. success: function() {
  387. // showToast 弹窗关闭后执行跳转
  388. self.switchTab(2)
  389. }
  390. });
  391. } catch (e) {
  392. console.error("添加数据,报错", e)
  393. }
  394. },
  395. switchTab(index) {
  396. this.activeTab = index; // 切换页面
  397. },
  398. async openSqlite() {
  399. // 打开数据库
  400. try {
  401. let b = await openSqlite()
  402. uni.showToast({
  403. title: "打开数据库成功",
  404. icon: "none"
  405. })
  406. } catch (e) {
  407. console.error("打开数据库,报错", e)
  408. }
  409. },
  410. // 创建表
  411. async createTable() {
  412. let sql = this.createTableSql_outbound()
  413. try {
  414. let exist = await isTable(this.tableName)
  415. console.log("表是否存在", exist)
  416. if (!exist) {
  417. let res = await executeSql(sql)
  418. uni.showToast({
  419. title: "新增数据表成功",
  420. icon: "none"
  421. })
  422. console.log("新增表ord_storage_order", res)
  423. } else {
  424. // uni.showToast({
  425. // title: "数据表已存在",
  426. // icon: "none"
  427. // })
  428. }
  429. } catch (e) {
  430. uni.showToast({
  431. title: "新增数据表失败",
  432. icon: "none"
  433. })
  434. console.error("新增表报错ord_storage_order", e)
  435. }
  436. },
  437. // 创建选样表
  438. async createDetailTable() {
  439. let sql = this.createTableSql_detail()
  440. try {
  441. let exist = await isTable('detail')
  442. console.log("表是否存在", exist)
  443. if (!exist) {
  444. let res = await executeSql(sql)
  445. uni.showToast({
  446. title: "新增数据表成功",
  447. icon: "none"
  448. })
  449. console.log("新增表detail", res)
  450. } else {
  451. // uni.showToast({
  452. // title: "数据表已存在",
  453. // icon: "none"
  454. // })
  455. }
  456. } catch (e) {
  457. uni.showToast({
  458. title: "新增数据表失败",
  459. icon: "none"
  460. })
  461. console.error("新增表报错ord_storage_order", e)
  462. }
  463. },
  464. /**
  465. * 创建表, 仅供参考
  466. * @returns {string}
  467. * 因为java后台用的id,所以这里用fid 作为自增id
  468. */
  469. createTableSql_outbound() {
  470. return "CREATE TABLE IF NOT EXISTS `public` (" +
  471. " `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
  472. " `uid` varchar(20) DEFAULT NULL ," +
  473. " `exhibitionName` varchar(50) DEFAULT NULL ," +
  474. " `customerName` varchar(50) DEFAULT NULL ," +
  475. " `receiver` varchar(50) DEFAULT NULL ," +
  476. " `exhibitionNote` varchar(500) DEFAULT NULL ," +
  477. " `fileSavePath` varchar(2000) DEFAULT NULL ," +
  478. " `createTime` datetime DEFAULT NULL default(datetime('now','localtime')) ," +
  479. " `updateTime` datetime DEFAULT NULL default(datetime('now','localtime')) ," +
  480. " `deleted` char(1) DEFAULT '0' " +
  481. "); "
  482. },
  483. createTableSql_detail() {
  484. return "CREATE TABLE IF NOT EXISTS `detail` (" +
  485. " `id` INTEGER PRIMARY KEY AUTOINCREMENT," +
  486. " `publicId` varchar(20) NOT NULL ," +
  487. " `barCode` varchar(50) NOT NULL ," +
  488. " `bpQuantity` INT NOT NULL ," +
  489. " `gyQuantity` INT NOT NULL ," +
  490. " `myQuantity` INT NOT NULL ," +
  491. " `note` varchar(500) DEFAULT NULL ," +
  492. " `fileSavePath` varchar(2000) DEFAULT NULL ," +
  493. " `createTime` TEXT DEFAULT NULL default(datetime('now','localtime')) ," +
  494. " `updateTime` TEXT DEFAULT NULL default(datetime('now','localtime')) ," +
  495. " `deleted` char(1) DEFAULT '0' " +
  496. "); "
  497. },
  498. // 添加数据
  499. async addData() {
  500. const uniqueId = Date.now().toString();
  501. const result = this.fileSavePath.join(','); // 使用逗号作为分隔符
  502. try {
  503. let b = await addSql(this.tableName, {
  504. uid: uniqueId,
  505. exhibitionName: this.baseData.exhibitionName,
  506. customerName: this.baseData.customerName,
  507. receiver: this.baseData.receiver,
  508. exhibitionNote: this.baseData.exhibitionNote,
  509. fileSavePath: result
  510. })
  511. console.log('vvvvvv', b)
  512. uni.showToast({
  513. title: "添加成功",
  514. icon: "none"
  515. });
  516. this.switchTab(1)
  517. } catch (e) {
  518. console.error("添加数据,报错", e)
  519. }
  520. },
  521. },
  522. };
  523. </script>
  524. <style>
  525. .container {
  526. position: relative;
  527. width: 100%;
  528. height: 100vh;
  529. overflow: hidden;
  530. /* 隐藏溢出内容,禁止滚动 */
  531. }
  532. .header {
  533. position: fixed;
  534. background-color: #253a6f;
  535. height: 170rpx;
  536. width: 100%;
  537. z-index: 1;
  538. display: flex;
  539. }
  540. /* .second-element {
  541. position: fixed;
  542. top: 170rpx;
  543. background-color: #253a6f;
  544. height: 100rpx;
  545. width: 100%;
  546. }
  547. .absolute-element {
  548. position: absolute;
  549. padding: 0 20px;
  550. width: 100%;
  551. top: 80px;
  552. } */
  553. .scroll-view {
  554. position: absolute;
  555. left: 50%;
  556. top: 60%;
  557. transform: translate(-50%, -50%);
  558. width: 90%;
  559. height: 100%;
  560. overflow: auto;
  561. /* 设置滚动 */
  562. background-color: white;
  563. border-radius: 5px;
  564. /* border: 1px solid red; */
  565. padding: 0 20px;
  566. z-index: 999;
  567. }
  568. .content {
  569. width: 100%;
  570. margin-bottom: 100px;
  571. /* 此处设置滚动区域的内容样式 */
  572. }
  573. /* .segmented-control {
  574. display: flex;
  575. border-bottom: 1px solid #ccc;
  576. } */
  577. .segmented-control-item {
  578. flex: 1;
  579. text-align: center;
  580. padding: 10px;
  581. color: white;
  582. }
  583. /* .segmented-control-item.active {
  584. background-color: #ccc;
  585. } */
  586. .underline {
  587. bottom: 0;
  588. left: 0;
  589. width: 20%;
  590. height: 1px;
  591. background-color: white;
  592. /* 设置下划线的颜色 */
  593. display: none;
  594. margin: 0 auto;
  595. }
  596. .segmented-control-item.active .underline {
  597. display: block;
  598. }
  599. .card-bottom {
  600. touch-action: none;
  601. // height: 60px;
  602. position: fixed;
  603. bottom: 0;
  604. width: 100%;
  605. z-index: 999;
  606. background-color: white;
  607. border-top: 1px;
  608. display: flex;
  609. flex-direction: column;
  610. }
  611. </style>