index.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <template>
  2. <div class="price-editor">
  3. <s-header :name="$t('device.modifyPricePage.title')" :noback="false" />
  4. <div class="content-container">
  5. <!-- 设备信息卡片 -->
  6. <div class="device-card">
  7. <div class="device-header">
  8. <div class="header-indicator"></div>
  9. <h3 class="device-name">
  10. {{ $t("device.modifyPricePage.equipmentName") }}:{{
  11. equipmentName
  12. }}
  13. </h3>
  14. </div>
  15. </div>
  16. <!-- 商品列表卡片 -->
  17. <div class="goods-card">
  18. <!-- 操作头部 -->
  19. <div class="card-header">
  20. <div class="goods-count">
  21. {{ $t("device.modifyPricePage.total") }}
  22. <span class="highlight">{{ tableData.length }}</span>
  23. {{ $t("device.modifyPricePage.goods") }}
  24. </div>
  25. <van-button
  26. icon="edit"
  27. plain
  28. hairline
  29. @click="noticeClk"
  30. class="batch-btn"
  31. >
  32. {{ $t("device.modifyPricePage.batchModify") }}
  33. </van-button>
  34. </div>
  35. <!-- 商品列表 -->
  36. <div class="goods-list">
  37. <div
  38. v-for="(item, index) in tableData"
  39. :key="index"
  40. class="goods-item"
  41. >
  42. <div class="goods-info">
  43. <van-image
  44. class="goods-image"
  45. :src="showSugerPhoto(item)"
  46. fit="cover"
  47. />
  48. <span class="goods-name">{{ item.productName }}</span>
  49. </div>
  50. <div class="price-action">
  51. <template v-if="item.isEdit">
  52. <van-field
  53. type="number"
  54. v-model="item.rmbPrice"
  55. class="price-input"
  56. :border="false"
  57. clearable
  58. >
  59. <template #extra>
  60. <span class="currency-symbol">{{ currencySymbol }}</span>
  61. </template>
  62. </van-field>
  63. <van-icon
  64. name="success"
  65. class="action-icon"
  66. @click="editClk(item, 2)"
  67. />
  68. </template>
  69. <template v-else>
  70. <div class="price-display">
  71. <span class="currency">{{ currencySymbol }}</span>
  72. <span class="price">{{ item.rmbPrice }}</span>
  73. </div>
  74. <van-icon
  75. name="edit"
  76. class="action-icon"
  77. @click="editClk(item, 1)"
  78. />
  79. </template>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. <!-- 批量修改弹窗 -->
  86. <kDialog
  87. :isCloseForConfirm="false"
  88. :dialogTitle="$t('device.modifyPricePage.batchPrice')"
  89. :confirmBtnTxt="$t('device.modifyPricePage.modifySubmit')"
  90. ref="kDialogRef"
  91. @confirmclk="confirmClk"
  92. >
  93. <template #content>
  94. <van-field
  95. type="number"
  96. v-model="cofficentForm.price"
  97. :placeholder="$t('device.modifyPricePage.batchPricePlace')"
  98. :label="$t('device.modifyPricePage.batchPrice')"
  99. class="batch-field"
  100. >
  101. <template #extra>
  102. <span class="currency-symbol">{{ currencySymbol }}</span>
  103. </template>
  104. </van-field>
  105. </template>
  106. </kDialog>
  107. </div>
  108. </template>
  109. <script>
  110. import kDialog from "@/components/commom/kDialog/index.vue";
  111. // 导入接口
  112. import { selectProducts, Api_getUpdaProdPrice } from "@/service/device/index";
  113. import sHeader from "@/components/SimpleHeader";
  114. import { reactive, ref } from "@vue/reactivity";
  115. import { onMounted } from "@vue/runtime-core";
  116. import { useRoute } from "vue-router";
  117. import { showToast } from "vant";
  118. import { useI18n } from "vue-i18n";
  119. // import { styleUrl } from "../../../common/js/utils";
  120. export default {
  121. components: { sHeader, kDialog },
  122. setup() {
  123. // 引入语言
  124. const { t } = useI18n();
  125. // 批量修改弹窗
  126. const kDialogRef = ref(null);
  127. // 点击批量修改
  128. const noticeClk = () => {
  129. cofficentForm.price = "";
  130. kDialogRef.value.openDialog();
  131. };
  132. // 点击确定按钮
  133. const confirmClk = () => {
  134. if (!cofficentForm.price) {
  135. showToast(t("device.modifyPricePage.batchPricePlace"));
  136. return;
  137. }
  138. cofficentForm.no = "";
  139. cofficentForm.type = 1;
  140. updatePrice();
  141. kDialogRef.value.closeDialog();
  142. };
  143. // 商品图片路径处理
  144. const showSugerPhoto = (row) => {
  145. let imgId = row.no;
  146. if (imgId) {
  147. return require(`../../../assets/order/spunSugar/goods/${imgId}.png`);
  148. }
  149. return imgId;
  150. };
  151. // 路由
  152. const route = useRoute();
  153. // 商品数据
  154. const tableData = ref([]);
  155. // 设备名称
  156. const equipmentName = ref("");
  157. // 刚进页面
  158. onMounted(() => {
  159. // 加载样式
  160. // styleUrl("modifyPrice");
  161. const id = route.query.deviceId || "";
  162. const name = route.query.name || "";
  163. if (id) {
  164. cofficentForm.equipmentId = id;
  165. equipmentName.value = name;
  166. getList();
  167. }
  168. });
  169. // 获取商品列表
  170. const getList = () => {
  171. selectProducts({ equipmentId: cofficentForm.equipmentId }).then((res) => {
  172. console.log("res", res);
  173. const { data } = res.data;
  174. if (data) {
  175. if (data.length > 0) {
  176. // 是否修改状态
  177. data.forEach((item) => {
  178. item.isEdit = false;
  179. });
  180. }
  181. tableData.value = data;
  182. }
  183. });
  184. };
  185. // 修改的价格
  186. const cofficentForm = reactive({
  187. equipmentId: "",
  188. no: "",
  189. price: "",
  190. type: "",
  191. });
  192. // 自定义货币符号
  193. const currencySymbol = ref("¥");
  194. const loginUserStr = localStorage.getItem("loginUser");
  195. const loginUser = JSON.parse(loginUserStr);
  196. if (loginUser.currencySymbol) {
  197. currencySymbol.value = loginUser.currencySymbol;
  198. } else {
  199. currencySymbol.value = "¥";
  200. }
  201. // 点击修改
  202. const editClk = (row, idx) => {
  203. // 如果点击的是修改
  204. if (idx === 1) {
  205. tableData.value.forEach((item) => {
  206. if (row.id !== item.id) {
  207. item.isEdit = false;
  208. }
  209. });
  210. row.isEdit = !row.isEdit;
  211. } else {
  212. cofficentForm.no = row.no;
  213. cofficentForm.price = row.rmbPrice;
  214. cofficentForm.type = 0;
  215. updatePrice(row);
  216. }
  217. };
  218. // 修改价格
  219. const updatePrice = (row) => {
  220. console.log("cofficentForm", cofficentForm);
  221. // 如果点击的是提交
  222. Api_getUpdaProdPrice(cofficentForm).then((res) => {
  223. showToast(res.data.message);
  224. if (row) {
  225. row.isEdit = false;
  226. }
  227. setTimeout(() => {
  228. getList();
  229. }, 500);
  230. });
  231. };
  232. return {
  233. cofficentForm,
  234. editClk,
  235. tableData,
  236. showSugerPhoto,
  237. kDialogRef,
  238. noticeClk,
  239. confirmClk,
  240. equipmentName,
  241. currencySymbol,
  242. };
  243. },
  244. };
  245. </script>
  246. <style lang="less" scoped>
  247. @primary-color: #4d6add;
  248. @card-bg: #ffffff;
  249. @text-primary: #2d3436;
  250. @border-color: #e4e7ec;
  251. .price-editor {
  252. background: #f8fafb;
  253. min-height: 100vh;
  254. .content-container {
  255. background: #f7f8fa;
  256. height: calc(100% - 50px);
  257. overflow: auto;
  258. overflow-x: hidden;
  259. }
  260. }
  261. .device-card {
  262. background: @card-bg;
  263. border-radius: 12px;
  264. box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  265. margin: 10px;
  266. padding: 16px;
  267. .device-header {
  268. display: flex;
  269. align-items: center;
  270. .header-indicator {
  271. width: 3px;
  272. height: 20px;
  273. background: @primary-color;
  274. margin-right: 12px;
  275. border-radius: 2px;
  276. }
  277. .device-name {
  278. margin: 0;
  279. font-size: 15px;
  280. color: #404d74;
  281. font-weight: 550;
  282. // 长名称处理
  283. overflow: hidden;
  284. text-overflow: ellipsis;
  285. white-space: nowrap;
  286. max-width: 70vw;
  287. }
  288. }
  289. }
  290. .goods-card {
  291. background: @card-bg;
  292. border-radius: 12px;
  293. box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  294. padding: 16px;
  295. margin: 10px;
  296. .card-header {
  297. display: flex;
  298. justify-content: space-between;
  299. align-items: center;
  300. margin-bottom: 20px;
  301. .goods-count {
  302. color: #666;
  303. .highlight {
  304. color: @primary-color;
  305. font-weight: 500;
  306. margin: 0 4px;
  307. }
  308. }
  309. .batch-btn {
  310. height: 32px;
  311. padding: 0 16px;
  312. font-size: 13px;
  313. }
  314. }
  315. }
  316. .goods-list {
  317. .goods-item {
  318. display: flex;
  319. justify-content: space-between;
  320. align-items: center;
  321. padding: 12px 0;
  322. border-bottom: 1px solid @border-color;
  323. &:last-child {
  324. border-bottom: none;
  325. }
  326. .goods-info {
  327. display: flex;
  328. align-items: center;
  329. flex: 1;
  330. .goods-image {
  331. width: 48px;
  332. height: 48px;
  333. border-radius: 6px;
  334. margin-right: 12px;
  335. }
  336. .goods-name {
  337. font-size: 14px;
  338. color: @text-primary;
  339. max-width: 200px;
  340. .ellipsis();
  341. }
  342. }
  343. .price-action {
  344. display: flex;
  345. align-items: center;
  346. gap: 12px;
  347. .price-input {
  348. width: 120px;
  349. background: #f8fafb;
  350. border-radius: 6px;
  351. padding: 4px 12px;
  352. :deep(.van-field__control) {
  353. text-align: right;
  354. }
  355. }
  356. .currency-symbol {
  357. color: @primary-color;
  358. margin-left: 4px;
  359. }
  360. .price-display {
  361. color: #df5e4c;
  362. font-size: 15px;
  363. }
  364. .action-icon {
  365. color: @primary-color;
  366. font-size: 20px;
  367. padding: 8px;
  368. }
  369. }
  370. }
  371. }
  372. .batch-field {
  373. :deep(.van-field__label) {
  374. width: 100px;
  375. }
  376. }
  377. .ellipsis() {
  378. overflow: hidden;
  379. text-overflow: ellipsis;
  380. white-space: nowrap;
  381. }
  382. @media (max-width: 480px) {
  383. .goods-card {
  384. padding: 12px;
  385. .goods-item {
  386. .goods-name {
  387. max-width: 160px;
  388. }
  389. }
  390. }
  391. }
  392. :deep(.van-image__img) {
  393. object-fit: contain !important;
  394. }
  395. </style>